所有的类集操作的接口或类都在 java.util 包中。
java类集结构图:
Collection 接口是在整个 Java 类集中保存单值的最大操作父接口,里面每次操作的时候都只能保存一个对象的数据。
此接口定义在 java.util 包中
public interface Collection<E> extends Iterable<E>
此接口使用了泛型技术,在JDK1.5之后为了使类集操作更加安全,所以引用了泛型。
Iterable也是一个接口,方法如下,所以Collection接口也具有该方法
boolean | add(E e) | 确保此集合包含指定的元素(可选操作)。 |
---|---|---|
boolean | addAll(Collection c) | 将指定集合中的所有元素添加到此集合中(可选操作)。 |
void | clear() | 从此集合中删除所有元素(可选操作)。 |
boolean | contains(Object o) | 如果此collection包含指定的元素,则返回 true 。 |
boolean | containsAll(Collection c) | 如果此集合包含指定集合中的所有元素,则返回 true 。 |
boolean | equals(Object o) | 将指定对象与此集合进行比较以获得相等性。 |
int | hashCode() | 返回此集合的哈希码值。 |
boolean | isEmpty() | 如果此集合不包含任何元素,则返回 true 。 |
Iterator | iterator() | 返回此集合中元素的迭代器。 |
boolean | remove(Object o) | 从此集合中移除指定元素的单个实例(如果存在)(可选操作)。 |
boolean | removeAll(Collection c) | 删除此集合的所有元素,这些元素也包含在指定的集合中(可选操作)。 |
default boolean | removeIf(Predicate filter) | 删除此集合中满足给定谓词的所有元素。 |
boolean | retainAll(Collection c) | 仅保留此集合中包含在指定集合中的元素(可选操作)。 |
int | size() | 返回此集合中的元素数。 |
Object[] | toArray() | 返回包含此集合中所有元素的数组。 |
T[] | toArray(T[] a) | 返回一个包含此collection中所有元素的数组; 返回数组的运行时类型是指定数组的运行时类型。 |
但是,在开发中不会直接使用 Collection 接口。而使用其操作的子接口:List、Set。
以前最早开始都是使用Collection操作的,但是后面为了更加清楚的区分——集合中是否允许有重复的元素,所以sun在其开源项目——PetShop(宠物商店)中开始推广List和Set使用。
在整个集合中 List 是 Collection 的子接口,里面的所有内容都是允许重复的。此接口上依然使用了泛型技术
public interface List<E> extends Collection<E>
除collection接口以外的10个方法:
NO | 方法名称 | 描述 |
---|---|---|
1 | public void add(int index,E element) | 在指定位置处增加元素 不能添加null,不能超过范围, 否则抛出异常 |
2 | boolean addAll(int index,Collection<? extends E> c) | 在指定位置处添加一组元素 |
3 | public E get(int index) | 根据索引位置取出每一个元素 |
4 | public int indexOf(Object o) | 根据对象查找指定的位置,找不到返回-1 |
5 | public int lastIndexOf(Object o) | 从后向前查找位置,找不到返回-1 |
6 | public ListIterator listIterator() | 返回ListIterator实例 |
7 | public ListIterator<E> listIterator(int index) | 返回从指定位置 ListIterator接口的实例 |
8 | public E remove(int index) | 删除指定位置的内容,并返回删除的元素 |
9 | public E set(int index,E element) | 修改指定位置的内容,并返回 |
10 | List<\E> subList(int fromIndex,int toIndex) | 返回子集合 |
此类定义如下:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
此类继承了AbstractList类。AbstractList类是List接口的子类。AbstractList是个抽象类,适配器设计模式。
demo:
public class ArrayListDemo02 { public static void main(String[] args) { List<String> all = new ArrayList<String>(); // 实例化List对象,并指定泛型类型 all.add("hello "); // 增加内容,此方法从Collection接口继承而来 all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的 all.add("world"); // 增加内容,此方法从Collection接口继承而来 all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的 all.remove("world");// 删除指定的对象 System.out.print("集合中的内容是:"); for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来 System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的 } } }
与ArrayList一样,也是List接口的子类
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable
该类与ArrayList操作没有区别,都是实现了List接口。
但是Vector 属于 java 元老级的操作类,是最早的提供了动态对象数组的操作类,在Jdk1.0的时候就已经推出了此类的使用,只是后来在 JDK 1.2 之后引入了 Java 类集合框架。但是为了照顾很多已经习惯于使用 Vector 的用户,所以在 JDK 1.2 之后将 Vector 类进行了升级了,让其多实现了一个 List 接口,这样才将这个类继续保留了下来。
demo:
public class ArrayListDemo02 { public static void main(String[] args) { List<String> all = new Vector<String>(); // 实例化List对象,并指定泛型类型 all.add("hello "); // 增加内容,此方法从Collection接口继承而来 all.add(0, "LAMP ");// 增加内容,此方法是List接口单独定义的 all.add("world"); // 增加内容,此方法从Collection接口继承而来 all.remove(1); // 根据索引删除内容,此方法是List接口单独定义的 all.remove("world");// 删除指定的对象 System.out.print("集合中的内容是:"); for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来 System.out.print(all.get(x) + "、"); // 此方法是List接口单独定义的 } } }
NO | 区别点 | ArrayList | Vector |
---|---|---|---|
1 | 时间 | 是新类,在JDK1.2之后推出的 | 是旧类,在JDK1.1的时候就定义了 |
2 | 性能 | 性能较高,采用了异步处理 | 性能较低,是采用了同步处理 |
3 | 输出 | 支持Iterator,ListIterator输出 | 除了支持Iterator,List Iterator 还支持 Enumeration输出 |
链表操作类,定义如下:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable
此类继承了 AbstractList,所以是 List 的子类。但是此类也是 Queue 接口的子类,Queue 接口定义了如下的方法:
NO | 方法名称 | 描述 |
---|---|---|
1 | public boolean add(E e) | 增加元素,如果有容量限制,并且已满,则抛出异常 |
2 | public E element() | 取得,但是不删除当前元素,如果对列为空则抛出异常 |
3 | boolean offer(E e) | 添加,如果有容量限制,并且已满,只是无法添加, 但不抛出异常,返回 false |
4 | E peek() | 取得头元素,但是不删除,如果队列为空,则返回null |
5 | E poll() | 取得头元素,但是删除, 如果队列为空,则返回 null |
6 | E remove() | 删除当前元素,如果队列为空则抛出异常 |
demo:用LinkedList实现队列
public class TestDemo { public static void main(String[] args) { Queue<String> queue = new LinkedList<String>(); queue.add("A"); queue.add("B"); queue.add("C"); int len=queue.size();//把queue的大小先取出来,否则每循环一次,移除一个元素,就少 一个元素,那么queue.size()在变小,就不能循环queue.size()次了。 for (int x = 0; x <len; x++) { System.out.println(queue.poll()); } System.out.println(queue); } }
Set 接口也是 Collection 的子接口,与 List 接口最大的不同在于,Set 接口里面的内容是不允许重复的
Set 接口并没有对 Collection 接口进行扩充,基本上还是与 Collection 接口保持一致。
遍历Set只能使用迭代器
此接口有两个子类:HashSet,TreeSet
常用方法全部来自Collection接口的方法
demo:
public class HashSetDemo01 { public static void main(String[] args) { Set<String> all = new HashSet<String>(); // 实例化Set接口对象 all.add("A"); all.add("B"); all.add("C"); all.add("D"); all.add("E"); System.out.println(all); //输出的是地址值 } }
通过循环对set输出:
public class HashSetDemo02 { public static void main(String[] args) { Set<String> all = new HashSet<String>(); // 实例化Set接口对象 all.add("A"); all.add("B"); all.add("C"); all.add("D"); all.add("E"); Object obj[] = all.toArray(); // 将集合变为对象数组 for (int x = 0; x < obj.length; x++) { System.out.print(obj[x] + "、"); } } }
验证Set接口不能有重复元素:
public class HashSetDemo04 { public static void main(String[] args) { Set<String> all = new HashSet<String>(); // 实例化Set接口对象 all.add("A"); all.add("A"); // 重复元素 all.add("A"); // 重复元素 all.add("A"); // 重复元素 all.add("A"); // 重复元素 all.add("B"); all.add("C"); all.add("D"); all.add("E"); Object obj[] = all.toArray(); // 将集合变为对象数组 for (int x = 0; x < obj.length; x++) { System.out.print(obj[x] + "、");// 结果里面只有一个A } } }
与 HashSet 不同的是,TreeSet 本身属于排序的子类,此类的定义如下:
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable
排序: 虽然在增加元素的时候属于无序的操作,但是增加之后却可以为用户进行排序功能的实现。
排序的说明:
自定义类排序需要提供排序排序接口Comparable 和 Comparator ,否则会报java.lang.ClassCastException错误
请看Comparable 和 Comparator接口博客如果要想判断两个对象是否相等,则必须使用 Object 类中的 equals()方法。
从最正规的来讲,如果要想判断两个对象是否相等,则有两种方法可以完成:
第一种判断两个对象的编码是否一致,这个方法需要通过 hashCode()完成,即:每个对象有唯一的编码
还需要进一步验证对象中的每个属性是否相等,需要通过 equals()完成。
所以此时需要覆写 Object 类中的 hashCode()方法,此方法表示一个唯一的编码,一般是通过公式计算出来的
所以如果要想去掉重复元素需要依靠 hashCode()和 equals()方法共同完成。
Iterator 属于迭代输出,基本的操作原理:是不断的判断是否有下一个元素,有的话,则直接输出。
此接口定义如下:
public interface Iterator<E>
使用:
要想使用此接口,则必须使用 Collection 接口,在 Collection 接口中规定了一个 iterator()方法,可以用于为 Iterator 接口进行实例化操作。
方法:
NO | 方法名称 | 描述 |
---|---|---|
1 | boolean hasNext() | 是否有下一个元素 |
2 | E next() | 取出内容 |
3 | void remove() | 删除当前内容 |
注意:
获得实例化后,Iterator 中的操作指针是在第一条元素之上,当调用 next()方法的时候,获取当前指针指向的值并向下移动,使用 hasNext()可以检查序列中是否还有元素。
ListIterator 是可以进行双向输出的迭代接口,此接口定义如下:
public interface ListIterator<E> extends Iterator<E>
方法:
NO | 方法名称 | 描述 |
---|---|---|
1 | void add(E e) | 增加元素 |
2 | boolean hasPrevious() | 判断是否有前一个元素 |
3 | E previous() | 取出前一个元素 |
4 | void set(E e) | 修改元素的内容 |
5 | int previousIndex() | 前一个索引位置 |
6 | int nextIndex() | 下一个索引位置 |
这个本人用的最多!!!!
注意:里面的操作泛型要指定具体的类型,这样在输出的时候才会更加有针对性。
Map接口是操作一对对象的接口,类似与:
保存以上信息 的时候 collection就不那么方便了,就要使用Map接口。
存储方式: key --> value 的形式保存。
此接口定义如下:
public interface Map<K,V>
这是第二大的集合操作接口
常用方法如下:
NO | 方法名称 | 描述 |
---|---|---|
1 | void clear() | 清空Map集合中的内容 |
2 | boolean containsKey(Object key) | 判断集合是否存在指定的key |
3 | boolean containsValue(Object value) | 判断集合是否存在指定的value |
4 | Set<Map.Entry<K,V>> entrySet() | 将Map接口变为Set集合 |
5 | V get(Object key) | 根据key找到其对应的value |
6 | boolean isEmpty() | 判断是否为空 |
7 | Set<K> keySet() | 将全部的key 变为Set集合 |
8 | Collection<V> values() | 将全部的value变为Collection集合 |
9 | V put(K key , V value) | 向集合中添加内容 |
10 | void putAll(Map<? extends K,? extends V> m) | 添加一组集合 |
11 | V remove(Object key) | 根据key 删除内容 |
它的子类:
此类定义:
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
此类继承了 AbstractMap 类,同时可以被克隆,可以被序列化下来
demo:
public class demo3 { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put("key1","value1"); map.put("key2","value2"); map.put("key3","value3"); // 使用get获取值 System.out.println(map.get("key1")); // 获取所有的key Set<String> keySet = map.keySet(); for (String s : keySet) { System.out.println(s + " - > " + map.get(s)); } // 获取所有的 value Collection<String> values = map.values(); for (String value : values) { System.out.println(value); } } }
运行结果:
value1 key1 - > value1 key2 - > value2 key3 - > value3 value1 value2 value3
Hashtable 是一个最早的 keyvalue 的操作类,本身是在 JDK 1.0 的时候推出的。其基本操作与 HashMap 是类似的。
**注意:**但是 Hashtable 中是不能向集合中插入 null 值的。
NO | 区别点 | HashMap | HashTable |
---|---|---|---|
1 | 时间 | 是新类,在JDK1.2之后推出的 | 是旧类,在JDK1.1的时候就定义了 |
2 | 性能 | 性能较高,采用了异步处理 | 性能较低,是采用了同步处理 |
3 | null | 支持Iterator,ListIterator输出 | 不允许设置null, 否则将出现空指针异常 |
TreeMap 子类是允许 key 进行排序的操作子类,其本身在操作的时候将按照 key 进行排序,另外,key 中的内容可以 为任意的对象,
但是要求对象所在的类必须实现 Comparable 接口。
当用对象作为key时,不能修改对象里面的值,否则会出现错误!!!!
demo:
public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("ZS", "张三"); map.put("LS", "李四"); map.put("WW", "王五"); map.put("ZL", "赵六"); map.put("SQ", "孙七"); for (Map.Entry<String, String> me : map.entrySet()) { System.out.println(me.getKey() + " --> " + me.getValue()); } }
Collections 实际上是一个集合的操作类,此类的定义如下:
public class Collections extends Object
此类仅包含对集合进行操作或返回集合的静态方法。 它包含对集合进行操作的多态算法,“包装器”,它返回由指定集合支持的新集合,以及其他一些可能性和结束。
public static <T> boolean addAll(Collection<T> c, T... elements);//:往集合中添加一些元素 public static void shuffle(List<?> list) // 打乱集合顺序 public static <T> void sort(List<T> list) //将集合中的元素按照默认规则排序 public static <T> void sort(List<T> list,Comparator<? super T> )// 按照指定规则排序
方法参考API