Java中通常用数组来存储多个值,但是数组的长度是固定的,一旦需要存储的元素大于数组长度就需要重新声明数组。因此在不确定存储元素的个数时应该使用集合。
首先给出Java中重要集合的继承体系:
这些接口和实现类是日常中经常使用的,其中List和Set继承了Collection接口,而ArrayList、LinkedList、Vector是List接口的实现类,HashSet和TreeSet是Set接口的实现类。
(一)Collection接口
Collection是一个接口,里面定义了一些集合共有的方法。
boolean add(E e) 添加元素 boolean remove(Object o) 删除元素 void clear() 清除元素 boolean contains(Object o) 包含某一个元素 boolean isEmpty() 判断集合是否为空 int size() 获取集合的大小 boolean addAll(Collection c) 把集合2添加到集合1 boolean removeAll(Collection c) 把集合2中所有元素从集合1中删除 boolean containsAll(Collection c) 判断集合2中所有的元素在集合1中是否都有 boolean retainAll(Collection c) 取两个集合的交集 Object[] toArray() 将集合转为Object数组 Iterator<E> iterator() 迭代器
遍历Collection集合:
Collection<String> collection = new ArrayList<String>(); //由于Collection为接口,所以用ArrayList来声明 collection.add("java"); collection.add("php"); collection.add("python"); collection.add("scala"); collection.add("swift"); collection.add("c++"); //第一种:利用Collection的toArray()方法转为Object[]数组 Object[] strArr = collection.toArray(); System.out.println(Arrays.toString(strArr)); //第二种:利用Collection的iterator()方法来迭代遍历,通过hasNext()和next() Iterator<String> iterator = collection.iterator(); while(iterator.hasNext()){ String lang = iterator.next(); System.out.println(lang); } //第三种:利用增强for循环 for(String lang: collection){ System.out.println(lang); }
(二)List接口
List是Collection的子接口,除了继承的一些方法,自己还声明了一些新方法,相比于Collection接口,它提供了在指定位置上进行增删改查的操作,这是因为List是一个有序的集合,这里的有序是指元素是会按照插入的顺序排列。
void add(int index, E element) 在指定位置添加元素 E get(int index) 获取指定位置的元素 ListIterator<E> listIterator() 迭代器 E remove(int index) 从集合中移除某个位置的元素 E set(int index, E element) 修改某个位置的元素
List list = new ArrayList(); list.add("java"); list.add("php"); list.add("python"); System.out.println(list); //[java, php, python] list.add(0,"h5"); System.out.println(list);//[h5, java, php, python] list.remove(0); System.out.println(list);//[java, php, python] System.out.println(list.get(0));//java
由于List提供了get()方法来获取到指定位置元素,故可以通过for循环来遍历:
List list = new ArrayList(); list.add("java"); list.add("python"); list.add("php"); list.add("scala"); for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); }
注意:如果利用iterator方法来遍历List,并且在遍历的时候还在向集合中插入元素,则会报ConcurrentModificationException异常。
List<String> list = new ArrayList<String>(); list.add("java"); list.add("php"); list.add("python"); System.out.println(list); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String lang = iterator.next(); if (lang.equals("php")){ list.add("go"); //ConcurrentModificationException } } System.out.println(list);
这个问题可以通过List接口的listIterator()方法解决。
List<String> list = new ArrayList<String>(); list.add("java"); list.add("php"); list.add("python"); ListIterator<String> it = list.listIterator(); while(it.hasNext()){ String lang = it.next(); if (lang.equals("php")){ it.add("go"); } } System.out.println(list);
另外,如果想从后往前遍历,可以使用hasPrevious和previous方法。(只在ListIterator接口中有)
接下来介绍一些特殊的集合类以及方法:
(1)Vector集合(很少使用)
常用方法:
void addElement(E obj) 添加一个元素 int capacity() 当前集合的容量 E elementAt(int index) 获取指定索引的元素 Enumeration<E> elements()
例:利用Enumeration来遍历Vector:
Enumeration enumeration = vector.elements(); while(enumeration.hasMoreElements()){ System.out.println(enumeration.nextElement()); }
(2)LinkedList集合。
除了List接口的一些共有方法外,LinkedList也有一些特有的方法。
void addFirst(E e) 在第一个位置上添加元素 void addLast(E e) 在最后一个位置上添加元素 E getFirst() 获取第一个元素 E getLast() 获取最后一个元素 E removeFirst() 移除第一个元素 E removeLast() 移除最后一个元素 E pop() 从最后一个位置移除元素 void push(E e) 在最后一个位置添加元素
通过上面的方法可以自定义一个栈:
public class Demo01 { public static void main(String[] args) { Stack stack = new Stack(); stack.push("a"); stack.push("b"); stack.push("c"); stack.push("d"); System.out.println(stack); Object e = stack.pop(); System.out.println(e); System.out.println(stack); System.out.println(stack.length()); } } class Stack { private LinkedList list = new LinkedList(); public void push(Object e){ //入栈 list.addLast(e); } public Object pop(){ //出栈 Object e = list.getLast(); list.removeLast(); return e; } public int length(){ return list.size(); } @Override public String toString() { return list.toString(); } }
当然,也可以直接使用LinkedList定义的push和pop方法来进行入栈和出栈操作。
【注】关于ArrayList和LinkedList的比较:ArrayList的添加元素和删除元素慢(增加或者删除元素需要移动其他元素的位置),时间复杂度是O(n),但是查询和修改的速度快(根据索引),时间复杂度是O(1);而LinkedList的增加和删除较快(直接修改指针),查询和修改较慢(因为要遍历整个序列)。
原文地址:https://www.cnblogs.com/liualex1109/p/12155396.html