java集合之List接口及实现类
一、List子接口
- 
有序、有下标、可重复(可用for循环进行遍历) 
- 
方法: - 
add(int index,Object o):在index位置插入对象o 
- 
addAll(int index,COllection c):将一个集合中的元素添加到此集合中的index位置 
- 
get(int index):返回集合中指定位置的元素 
- 
subList(int fromIndex,int toIndex):返回fromIndex和toIndex之间的集合元素 
- 
... public class ListDemo { /** * List:有序、有下标、可重复 * @param args */ public static void main(String[] args) { List list=new ArrayList(); List list1=new ArrayList(); list1.add("苹果13promax"); list1.add("小米10"); //增加元素 list.add("苹果13promax"); list.add("小米10"); list.add(0,"红米K30S");//通过下标来插入 list.add(0,"红米K30"); list.add(0,"红米K40"); System.out.println(list.toString()); //删除元素 list.remove("小米10"); list.remove(1); System.out.println(list.toString()); //遍历 System.out.println("-----------------for------------------"); //1.for for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("-----------------foreach------------------"); //2.foreach for (Object o : list) { System.out.println(o); } System.out.println("-----------------iterator------------------"); //3.迭代器iterator Iterator iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } System.out.println("-----------------ListIterator()------------------"); //4.迭代器ListIterator ListIterator listIterator = list.listIterator(); while (listIterator.hasNext()){ listIterator.next(); }//此时游标已经到了最后一个对象的后面,因此可用下面的方式输出 while (listIterator.hasPrevious()){ System.out.println(listIterator.previous()); } System.out.println("-----------------ListIterator(index)------------------"); ListIterator listIterator1 = list.listIterator(1);//创建一个从1索引位置开始的List迭代器 while (listIterator1.hasNext()){ System.out.println(listIterator1.next()); } //判断 System.out.println(list.contains("苹果13promax"));//true System.out.println(list.contains("苹果13promax "));//false System.out.println(list.isEmpty()); } } //下面是第二个程序示例 public class ListDemo02 { public static void main(String[] args) { List list=new ArrayList(); list.add(20);//此处有自动装箱操作 list.add(40); list.add(50); list.add(60); //list.remove("40");//无法删除 //list.remove((Object)20);//需要先状装箱才能进行删除 //list.remove((Integer)40); System.out.println(list); //subList方法:截取List(包含头,不包含尾) List list2 = list.subList(1, 4); System.out.println(list2);//[40, 50, 60] } }
 
- 
- 
list实现类 - 
ArrayList: - 数组结构实现,查询快、增删慢(增加和删除要改变元素顺序)
- JDK1.2版本,运行效率快、线程不安全
 
- 
Vector(一般不用了): - 数组结构实现,查询快、增删慢
- JDK1.0,运行效率慢、线程安全
 
- 
LinkedList: - 
链表结构实现,查询慢,增删快 
- 
链表结构是通过一个个节点连接,首先有个头,头指向第二个节点,依次往下,因此在查询时,就比较慢,而删除的话只需要改变对下个结点的指向,因此比较快 
 
- 
 
- 
二、ArrayList
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList arrayList=new ArrayList();
        Student s1=new Student("韩邦胜",20);
        Student s2=new Student("宋平",20);
        Student s3=new Student("韩平",20);
        //新增
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        System.out.println(arrayList.size());
        System.out.println(arrayList);
        //删除
        arrayList.remove(new Student("韩平",20));//要使用这种方式删除,需要重写Student的equals方法
        System.out.println(arrayList.size());
        System.out.println(arrayList);
        //遍历
        System.out.println("——————————迭代器——————————");
        Iterator it = arrayList.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("——————————列表迭代器——————————");
        ListIterator lit = arrayList.listIterator();
        while(lit.hasNext()){
            System.out.println(lit.next());
        }
        System.out.println("——————————列表迭代器逆序——————————");
        while(lit.hasPrevious()){
            System.out.println(lit.previous());
        }
        //包含
        System.out.println(arrayList.contains(new Student("宋平",20)));
        System.out.println(arrayList.isEmpty());
        //查找
        System.out.println(arrayList.indexOf(new Student("宋平",20)));
    }
}
//以下为Student类:
public class Student {
    private String name;
    private int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        //1判断是不是同一个对象
        if (o==this){
            return true;
        }
        //2判断是不是null
        if (o==null){
            return false;
        }
        //3判断是不是Student类型
        if (o instanceof Student){
            //4判断属性值是否相等
            if (((Student) o).getName()==this.name&&((Student) o).getAge()==this.age){
                return true;
            }
        }
        //5否则返回false
        return false;
    }
}
- 
ArrayList源码分析 - 
DEFAULT_CAPACITY = 10 默认容量为10 
- 
size 数组大小 
 
- 
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}//ArrayList的构造方法,默认将DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组赋值给当前数组
```java
public boolean add(E e) {
  ensureCapacityInternal(size + 1);  // Increments modCount!!,每次传过去的值为size+1
  elementData[size++] = e;
  return true;
}//add方法
private void ensureCapacityInternal(int minCapacity) {
  ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//比较elementData和minCapacity大小返回大的
}
private void ensureExplicitCapacity(int minCapacity) {
  modCount++;
  // overflow-conscious code
  if (minCapacity - elementData.length > 0)
      grow(minCapacity);
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
  if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
       return Math.max(DEFAULT_CAPACITY, minCapacity);//将这个数于默认的容量10进行比较,返回大的
  }
    return minCapacity;
}
//扩容的核心代码
private void grow(int minCapacity) {
  // overflow-conscious code
  int oldCapacity = elementData.length;
  int newCapacity = oldCapacity + (oldCapacity >> 1);//右移1位,相当于除以2
  if (newCapacity - minCapacity < 0)
      newCapacity = minCapacity;
  if (newCapacity - MAX_ARRAY_SIZE > 0)
      newCapacity = hugeCapacity(minCapacity);
  // minCapacity is usually close to size, so this is a win:
  elementData = Arrays.copyOf(elementData, newCapacity);
}
- 结论:不调用add时ArrayList的容量为0,当调用add时,容量为10,当size为10时,ArrayList扩容,扩容大小为基础的1.5倍,即10*1.5=15,依次往下推。
三、Vector(用的不多)
import java.util.Enumeration;
import java.util.ListIterator;
import java.util.Vector;
public class VectorDemo {
    /**
     * 存储结构:数组 和ArrayList差不多,比ArrayList安全,但相对较慢
     * @param args
     */
    public static void main(String[] args) {
        Vector vector=new Vector();
        //1.添加
        vector.add("小米");
        vector.add("苹果");
        vector.add("华为");
        System.out.println(vector.size());
        System.out.println(vector);
        //2.删除
        //vector.remove(0);
        //vector.remove("苹果");
        //vector.clear();
        //System.out.println(vector);
        //3.遍历
        //ListIterator列表迭代器
        ListIterator lit = vector.listIterator();
        while(lit.hasNext()){
            System.out.println(lit.next());
        }
        //枚举器
        Enumeration enumeration = vector.elements();
        while (enumeration.hasMoreElements()){
            System.out.println(enumeration.nextElement());
        }
        //4.查找
        System.out.println(vector.contains("苹果"));
        System.out.println(vector.isEmpty());
        //5.其他方法
        System.out.println(vector.firstElement());
        System.out.println(vector.lastElement());
        System.out.println(vector.elementAt(0));//返回索引处的元素
    }
}
四、LinkedList
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class LinkedListDemo01 {
    public static void main(String[] args) {
        LinkedList linkedList=new LinkedList();
        Student s1=new Student("韩邦胜",20);
        Student s2=new Student("韩胜",21);
        Student s3=new Student("韩邦",22);
        //添加
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        System.out.println(linkedList.size());
        System.out.println(linkedList);
        //删除
//        linkedList.remove(0);
//        linkedList.remove(new Student("韩邦",22));
//        System.out.println(linkedList.size());
//        System.out.println(linkedList);
        //遍历
        //1.for
        System.out.println("---------for------------");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        //2.foreach
        System.out.println("---------foreach------------");
        for (Object obj:linkedList) {
            System.out.println(obj);
        }
        //3.iterator
        System.out.println("---------iterator------------");
        Iterator it = linkedList.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //4.listiterator
        System.out.println("---------listiterator------------");
        ListIterator lit = linkedList.listIterator();
        while(lit.hasNext()){
            System.out.println(lit.next());
        }
        //判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.indexOf(s1));
    }
}
- 
LinkedList源码分析 - size():大小
- first:头结点
- last:尾结点
- add()方法
 public boolean add(E e) { linkLast(e); return true; }- linkLast(e)
 void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }- Node类
 private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }- 分析linkLast,当添加第一个元素时,last为空,所以l为空,newNode调用Node类的构造方法,前一个为空,后一个也为空,将newNode赋值给last,l==null,所以first也是newNode。size++。
- 第二次add元素,last已经不是null了,newNode的前面指向last,并将last重新赋值为新的newNode,并将l的下个节点指向这个newNode,size++。
- 双向链表结构
- 删除的话只需要查到后断开那个链,接到下一个结点就行,因此比较快。
 
五、ArrayList和LinkedList区别
- ArrayList开辟的空间是连续的
- LinkedList开辟的空间不用是连续的

本文来自博客园,作者:一只快乐的小67,转载请注明原文链接:https://www.cnblogs.com/sp520/p/15934862.html
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号