Java集合之Collection与List知识点汇总

1,081 阅读5分钟

前言:

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

Java的类集框架比较多,也十分重要,在这里给出图解,可以理解为相应的继承关系,也可以当作重要知识点回顾;

Collection集合接口

Collection集合接口

继承自:Iterable

public interface Collection<E> extends Iterable<E>

java.util.Collection是单值集合操作的最大父接口,其中有几个核心操作方法以及常用操作方法;

Modifier and TypeMethod(public)Description
booleanadd(E e)确保此集合包含指定的元素(可选操作)。
booleanaddAll(Collection<? extends E> c)将指定集合中的所有元素添加到此集合(可选操作)。
voidclear()从集合中删除所有元素(可选操作)。
booleancontains(Object o)如果该集合包含指定的元素,则返回true。
booleanremove(Object o)如果存在,则从此集合中删除指定元素的单个实例(可选操作)。
intsize()返回此集合中的元素数。
Object[]toArray()返回一个包含此集合中所有元素的数组。
Iterator<E>iterator()返回对此集合中的元素进行迭代的迭代器。

上面方法中有两个特殊的方法就是cotainsremove;都需要equals方法的支持才能删除与查询数据;否则找不到元素。

后面都是衍生出的子类方法。

List集合

最大特点:允许保存重复的元素,并在其父接口上扩充了其他的方法;

继承关系:

public interface List<E> extends Collection<E>
Modifier and TypeMethod(public)Description
voidadd(int index, E element)Inserts the specified element at the specified position in this list (optional operation).
booleanadd(E e)Appends the specified element to the end of this list (optional operation).
ListIterator<E>listIterator()Returns a list iterator over the elements in this list (in proper sequence).
static <E> List<E>of()Returns an unmodifiable list containing zero elements.
default voidforEach(Consumer<? super T> action)Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.

实例:

package Java从入门到项目实战.Java类集框架.List集合;
import java.util.List;
public class 多数据保存 {
    public static void main(String[] args) {
        List<String> all = List.of("xbhg","Hello","World","welcome");
        Object[] result = all.toArray();
        for (Object t: result) {
            System.out.println(t);
        }
        System.out.println("----------分割线----------");
        all.forEach(System.out::println); //方法引用部分的引用构造方法
    }
}

ArrayList子类

继承结构如下:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable

实例化:重复元素允许保存并且按照添加时的顺序保存;

package Java从入门到项目实战.Java类集框架.List集合;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArrayList实例化List {
    public static void main(String[] args) {
        List<String> all = new ArrayList<String>();
        all.add("Hello");
        all.add("你好");
        all.add("你好");
        all.add("xbhog");
        System.out.println(all);
        all.forEach(System.out::print);
        //lambda表达式
        all.forEach((str)->{
            System.out.print(str+"、");
        });
    }
}

集合操作方法:

package Java从入门到项目实战.Java类集框架.List集合;
import java.util.ArrayList;
import java.util.List;

public class ArrayLIst集合相关操作 {
    public static void main(String[] args) {
        List<String> all = new ArrayList<String>();
        System.out.println("集合是否为空?"+all.isEmpty()+"、集合元素个数"+all.size());
        all.add("1");
        all.add("2");
        all.add("3");
        System.out.println("集合是否为空?"+all.isEmpty()+"、集合元素个数"+all.size());
        System.out.println(all.get(1));
        System.out.println(all.remove("3"));
        System.out.println("集合是否为空?"+all.isEmpty()+"、集合元素个数"+all.size());
    }
}

ArrayList原理分析:重点

首先需要明确ArrayList是通过数组实现的;这样就出现了ArrayList通过什么样的方式进行的扩容操作,以及在什么情况下才会扩容?

ArrayList类中的数组是在构造方法中进行的空间开辟的;其对应的有无参和有参构造方法:

无参构造方法:使用空数组(长度为0)初始化,在第一次使用时会为其开辟空间为(初始化程度为10);

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//默认的开辟空间大小
private static final int DEFAULT_CAPACITY = 10;
/**
     * Shared empty array instance used for empty instances.
     */
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

有参构造方法:长度大于0则以指定长度开辟数组空间;如果长度为0,则按照无参构造方法进行;如果负数则抛出ILLegaLArgumentException异常;

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // defend against c.toArray (incorrectly) not returning Object[]
        // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

当数组扩充后利用数组复制的形式,将旧数组中的数据复制到开辟的新数组中;

其最大程度为:

/**
     * The maximum size of array to allocate (unless necessary).
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

ArrayList保存自定义类对象:

该操作必然包含了相关的增删改查;由于contains与remove方法的实现都需要通过对象比较俩完成;所以我们需要覆写equals方法

package Java从入门到项目实战.Java类集框架.List集合;

import java.util.ArrayList;
import java.util.List;

class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public boolean equals(Object obj){
        if(this== obj) return true;
        if(obj == null) return false;
        if(!(obj instanceof Person)) return false;
        Person pe = (Person) obj;
        return this.name.equals(pe.name) && this.age == pe.age;
    }

    @Override
    public String toString() {
        return "姓名:"+this.name +"、年龄:"+this.age;
    }
}
public class ArrayList保存自定义类对象 {
    public static void main(String[] args) {
        List<Person> std = new ArrayList<Person>();
        std.add(new Person("xbhog",1));
        std.add(new Person("小明",2));
        std.add(new Person("小白",3));
        System.out.println("-------删除前的数据内容----------");
        std.forEach((person)->{
            System.out.println("姓名:"+person.getName()+"、年龄:"+person.getAge());
        });
        System.out.println("-------删除后的数据内容----------");
        std.remove(new Person("小白",3));
        std.forEach((person)->{
            System.out.println("姓名:"+person.getName()+"、年龄:"+person.getAge());
        });
        System.out.println("-------查看数据是否存在----------");
        System.out.println(std.contains(new Person("小明",2)));
    }
}

LinkedList子类:

继承结构如下:基于链表形式的实现

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable

实现LinkedList的集合操作:

package Java从入门到项目实战.Java类集框架.List集合;

import java.util.LinkedList;
import java.util.List;

public class LinkList链表操作 {
    public static void main(String[] args) {
        List<String> all = new LinkedList<String>();
        all.add("java");
        all.add("python");
        all.add("Linux");
        System.out.println(all);
        System.out.println(all.get(2));
        System.out.println(all.get(1));
    }
}

Vector子类:

继承结构如下:

public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable

从继承结构上可以看出,Vector子类的使用方式与ArrayList的使用方式相同;

package Java从入门到项目实战.Java类集框架.List集合;
import java.util.List;
import java.util.Vector;
public class Vector子类实现List接口 {
    public static void main(String[] args) {
        List<String> all = new Vector<String>();
        all.add("asda");
        all.add("你好");
        all.add("buhao");
        System.out.println(all);
    }
}

不同点:

以下是vector操作方法,采用的方式是synchronized 同步处理;属于线程安全,但是效率没有ArrayList高;

在考虑线程并发访问的情况下才能去使用vector子类。

public synchronized void copyInto(Object[] anArray)

结束:

如果你看到这里或者正好对你有所帮助,希望能点个关注或者推荐,感谢;

有错误的地方,欢迎在评论指出,作者看到会进行修改。