Java--集合(List、ArrayList、Vector、LinkedList)
一、集合概念
对象的容器,实现了对对象常用的操作,类似数组功能
二、集合和数组的区别
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型(如果想存储基本类型,则需把基本类型装箱)
- 重点:迭代器专门用来遍历集合的一种方式
- hasNext();有没有下一个元素 有返回true,否则返回false
- next();获取下一个元素
- remove();删除当前元素
package com.monv.jihe; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * Collection接口的使用 * 1.添加元素 * 2.删除元素 * 3.遍历元素 * 4、判断 * @author Administrator * */ public class TestCollection { public static void main(String[] args) { //创建集合 Collection collection = new ArrayList(); //1.添加元素 collection.add("苹果"); collection.add("葡萄"); collection.add("草莓"); System.out.println("元素个数:"+collection.size()); System.out.println(collection); //2.删除 // collection.remove("葡萄"); // collection.clear();//清空 // System.out.println("元素个数:"+collection.size()); // System.out.println(collection); //3.遍历元素 //3.1 使用增强for(foreach) 不能用for循环 因为没有下标 System.out.println("-------使用增强for遍历----------"); for (Object object : collection) { System.out.println(object); } //3.2 使用迭代器(专门用来遍历集合的一种方式) //hasNext();有没有下一个元素 //next();获取下一个元素 //remove();删除当前元素 System.out.println("-------使用迭代器遍历---------"); Iterator it = collection.iterator(); while(it.hasNext()){ String str = (String)it.next(); System.out.println(str); // collection.remove(str);//迭代过程中不能用collection的其他方法来改变元素的 // it.remove();//可以用迭代器的方法remove()进行删除 } System.out.println(collection.size()); //4.判断 System.out.println("--------判断是否包含某个元素----------"); System.out.println(collection.contains("梨")); System.out.println(collection.contains("葡萄")); } }
三、List子接口
特点:有序(添加和遍历的顺序是一致的)、有下标、元素可以重复
方法:除了collection中的方法外,还包含其特有的方法
- void add(int index,Object o);//在index的位置插入对象o
- boolean addAll(int index,Collection c);//将一个集合中的元素添加到此集合中index位置
- Object get(int index);//返回集合中指定位置的元素
- List subList(int fromIndex,int toIndex);//返回fromIndex和toIndex之间集合元素 含首不含尾
package com.monv.jihe; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * List子接口的使用 * 特点:1.有序 有下标 2.可以重复 * @author Administrator * */ public class Demo1 { public static void main(String[] args) { //先创建集合对象 List list = new ArrayList(); //1.添加元素 list.add("苹果"); list.add("小米"); list.add(0, "华为"); System.out.println("元素个数:"+list.size()); System.out.println(list.toString()); //2.删除元素 // list.remove("苹果"); // list.remove(0); // System.out.println("删除后元素个数:"+list.size()); //3.遍历 //3.1for循环遍历 System.out.println("----3.1for循环遍历----"); for(int i=0;i<list.size();i++) { System.out.println(list.get(i)); } //3.2增强for循环遍历 System.out.println("----3.2增强for循环----"); for (Object object : list) { System.out.println(object); } //3.3使用迭代器 System.out.println("----3.3使用迭代器----"); Iterator it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //list 指针默认指向第一个元素 //3.4列表迭代器 System.out.println("----3.41列表迭代器(从前往后)----"); ListIterator lit = list.listIterator(); while(lit.hasNext()) { System.out.println(lit.nextIndex() +":"+lit.next()); } //如果使用从后往前迭代的话 指针需要指向最后一个元素 ,在上个循环的基础上 执行从后往前的迭代 System.out.println("---3.42列表迭代器(从后往前)---"); while (lit.hasPrevious()) { System.out.println(lit.previousIndex() + ":" + lit.previous()); } //4.判断 System.out.println("--------4.判断----------"); System.out.println(list.contains("苹果")); System.out.println(list.isEmpty()); //5.获取位置 System.out.println("--------5.获取位置--------"); System.out.println(list.indexOf("华为")); } } ------------------------------------------------------------------------- package com.monv.jihe; import java.util.ArrayList; import java.util.List; /** * List的使用 * @author Administrator * */ public class Demo2 { public static void main(String[] args) { //创建集合 List list = new ArrayList(); //1.添加数字数据(添加的时候包含自动装箱的操作 把基本类型转换为引用类型) list.add(20); list.add(30); list.add(40); list.add(50); list.add(60); System.out.println("集合元素的个数:"+list.size()); System.out.println(list.toString()); //2.删除操作 // list.remove(20);//注意:这里是根据index下标删除的 总共有5个元素 删除第20个元素 下标越界 会报错 // list.remove(0); // list.remove((Object)20);//把20转换为object类型后再进行删除 // list.remove(new Integer(20)); System.out.println("删除后元素个数:"+list.size()); //3.补充方法 subList:返回子集合 含头不含尾 System.out.println("-----subList-----"); List subList = list.subList(1, 3); System.out.println("子集合元素个数:"+subList.size()); System.out.println(subList.toString()); } }
四、 List实现类
4.1 ArrayList【重点】:数组结构实现,查询快、增删慢;JDK1.2版本,运行效率快、线程不安全
package com.monv.jihe; public class Student { private String name; private int age; public Student() { // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); 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 obj) { //1.判断是否是同一个对象 if(this == obj) { return true; } //2.判断是否为空 if(obj == null) { return false; } //3.判断是否是Student类型 if (obj instanceof Student) { Student s = (Student)obj; //4.比较属性 if (this.name.equals(s.getName())&&this.age == s.getAge()) { return true; } } //5.不满足返回false return false; } } -------------------------------------------- package com.monv.jihe; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; /** * ArrayList的使用 * 存储结构:数组,查找遍历速度快,增删慢 * @author Administrator * */ public class Demo3 { public static void main(String[] args) { //创建集合 size 0 容量0,扩容原来的1.5倍(当添加第11个元素的时候,容量扩到15) ArrayList arrayList = new ArrayList(); Student s1 = new Student("小明", 20); Student s2 = new Student("小红", 21); Student s3 = new Student("小花", 19); Student s4 = new Student("小芳", 18); //1.添加元素 arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); arrayList.add(s4); System.out.println("元素个数:"+arrayList.size()); System.out.println(arrayList.toString()); //2.删除元素 // arrayList.remove(0); // arrayList.remove(s2); //remove删除判断的时候是用equals(this==obj) 来判断两个对象的地址是否一样 //如果想用下面new一个对象的方式来删除s4 则需要在Student中重写equals让它来比较两个值是否一样 一样删除 在 arrayList.remove(new Student("小芳", 18)); System.out.println("删除后元素个数:"+arrayList.size()); //3.遍历元素【重点】 //3.1使用迭代器 System.out.println("--------3.1使用迭代器-------------"); Iterator it = arrayList.iterator(); while(it.hasNext()) { Student s = (Student)it.next(); System.out.println(s.toString()); } //3.2列表迭代器 System.out.println("--------3.2使用列表迭代器正向--------"); ListIterator lit= arrayList.listIterator(); while(lit.hasNext()) { Student s = (Student) lit.next(); System.out.println(s.toString()); } System.out.println("--------3.2使用列表迭代器逆向--------"); while(lit.hasPrevious()) { Student s = (Student) lit.previous(); System.out.println(s.toString()); } //4.判断 System.out.println(arrayList.contains(new Student("小明", 20)));//因为重写了equals 所以也可以用new的方式来比较值是否相同 System.out.println(arrayList.isEmpty());//判断是否为空 //5.查找 System.out.println(arrayList.indexOf(s3));//查找位置 } }
源码分析:DEFAULT_CAPACITY = 10; 默认容量
( 注意:如果没有向集合中添加任何元素,容量为0,当开始向集合中添加元素的时候,默认容量为10;每次扩容大小是原来的1.5倍)
elementData:存放元素的数组
size :实际元素的个数
add():添加元素
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } //数组扩容的方法 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); 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); }
4.2 Vector:数组结构实现,查询快,增删慢;JDK1.0版本,运行效率慢、线程安全
package com.monv.jihe; import java.util.Enumeration; import java.util.Vector; /** * 演示Vector集合使用 * 存储结构:数组 * @author Administrator * */ public class Demo4 { public static void main(String[] args) { //创建集合 Vector vector = new Vector(); //1.添加元素 vector.add("花生"); vector.add("小麦"); vector.add("玉米"); System.out.println("元素个数:"+vector.size()); //2.删除 // vector.remove("花生"); // vector.remove(2); // vector.clear();//清空 System.out.println("删除后元素个数:"+vector.size()); //3.遍历 使用枚举器 Enumeration en = vector.elements(); while(en.hasMoreElements()) { String s = (String)en.nextElement(); System.out.println(s); } //4.判断 System.out.println(vector.contains("花生")); System.out.println(vector.isEmpty());//是否为空
//5.其他方法firstElement() lastElement() elementAt() System.out.println(vector.firstElement()); System.out.println(vector.lastElement()); System.out.println(vector.elementAt(1)); } }
4.3LinkedList:链表结构实现,增删快,查询慢。第一个元素指向第二元素,然后依次类推,删除的时候,链表会重新指向另外的一个元素。因为有引用指向关系所以查询的时候比较慢。
package com.monv.jihe; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; /** * LinkedList 使用 * 存储结构:双向链表 * @author Administrator * */ public class Demo5 { public static void main(String[] args) { //创建集合 LinkedList linkedList = new LinkedList(); Student s1 = new Student("小明", 20); Student s2 = new Student("小红", 21); Student s3 = new Student("小花", 19); //1.添加元素 linkedList.add(s1); linkedList.add(s2); linkedList.add(s3); System.out.println("元素个数:"+linkedList.size()); System.out.println(linkedList.toString() ); //2.删除元素 // linkedList.remove(0); // linkedList.remove(s1); // linkedList.remove(new Student("小红", 21)); // linkedList.clear();//清空 System.out.println("删除后元素个数:"+linkedList.size()); //3.遍历 //3.1使用for遍历 System.out.println("----3.1使用for遍历----"); for(int i = 0;i<linkedList.size();i++) { System.out.println(linkedList.get(i)); } //3.2增强for循环 System.out.println("----3.2增强for循环----"); for (Object object : linkedList) { Student s = (Student)object; System.out.println(s.toString()); } //3.3使用迭代器 System.out.println("----3.3使用迭代器----"); Iterator it = linkedList.iterator(); while(it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.toString()); } //3.4使用列表迭代器 System.out.println("----3.4使用列表迭代器----"); ListIterator lit = linkedList.listIterator(); while(lit.hasNext()) { Student s = (Student) lit.next(); System.out.println(s.toString()); } //4.判断 System.out.println("----判断----"); System.out.println(linkedList.contains(s2)); System.out.println(linkedList.isEmpty()); //5.获取 System.out.println("----获取----"); System.out.println(linkedList.indexOf(s2)); } }
源码分析:
int size : 集合的大小
Node first : 链表的头节点
Node last :链表的尾节点
public boolean add(E e) { linkLast(e); return true; } 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++; } 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; } }
4.4 ArrayList和LinkedList 不同结构实现方式
- ArrayList(数组):必须开辟连续的空间,查询快,增删慢。而且有角标
- LinkedList(双向链表):无需开辟连续空间,查询慢,增删快
-
输出是最好的输入。把学习的内容输出出来,加深记忆;