由图上可知,集合分为Collection和Map两大体系。
集合比数组用起来更方便,它只能存储对象,(因为集合实际上存储的是对象的引用值,也就是在堆中的地址)。基本数据类型是存在栈内存里边的,所以不能存放基本数据类型必须经过包装类才可以存储。(例如想要存放int类型数据,则需要使用Integer包装类)
Collection(单元素集合)
Collection接口没有实现类,但是有子接口,子接口可以有实现类。
Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
用集合必须要使用泛型,泛型里面只能存储引用数据类型,并且该集合只能存储该数据类型的数据(除非存的是Object类型)
例如:LinkedList<Student> list = new LinkedList<>();(右边的尖括号里可写可不写)
Collection中有许多方法,这些方法可以被实现类所调用。
boolean | add(E e) 确保此 collection 包含指定的元素(可选操作)。 |
boolean | addAll(Collection<? extends E> c) 将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 |
void | clear() 移除此 collection 中的所有元素(可选操作)。 |
boolean | contains(Object o) 如果此 collection 包含指定的元素,则返回 true。 |
boolean | containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 true。 |
boolean | equals(Object o) 比较此 collection 与指定对象是否相等。 |
int | hashCode() 返回此 collection 的哈希码值。 |
boolean | isEmpty() 如果此 collection 不包含元素,则返回 true。 |
Iterator<E> | iterator() 返回在此 collection 的元素上进行迭代的迭代器。 |
boolean | remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 |
boolean | removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 |
boolean | retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 |
int | size() 返回此 collection 中的元素数。 |
Object[] | toArray() 返回包含此 collection 中所有元素的数组。 |
<T>T[ ] | toArray(T[] a) 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 |
这里要讲一下迭代器Iterator,迭代器其实就是一个类似于游标的东西,它在被实例化出来后存放在集合中的第0位的前面,是用来访问集合中的元素的
Iterator位于java.util包下,它有三个方法,都是用来遍历集合中的元素的(返回值里的E其实就是元素Element)
每一个容器都在其内部对该接口进行了内部类的实现,也就是将取出方式的细节进行封装。a是一个实现类,实现类的iterator方法返回的是接口实现类的对象,因此可以声明iterator接口来存储它的返回的iterator迭代器
boolean | hasNext() 如果仍有元素可以迭代,则返回 true。 |
E | next() 返回迭代的下一个元素。 |
void |
|
如果想要获取集合中的元素,那么就可以先让这个迭代器迭代到所需元素的下方,然后通过迭代器的next()方法来获取这个元素
相当于将它变成一个数组,在调用hashNext时,相当于有一个游标,初始位置是比第0位还要前面,如果迭代器还没有到最后,那就继续迭代
public static void main(String[] args) {
//1.2.7.定义一个Set,向Set中存储5个人名,其中有两个是重复的,输出Set集合的数据,通过for each,和Iterator两种方法。
Set<String> s = new HashSet();
s.add("aaa");
s.add("bbb");
s.add("ccc");
s.add("bbb");
s.add("ddd");
for (String i : s){
System.out.println(i);
}
Iterator<String> iterator = s.iterator();
while(iterator.hasNext()){
String a = iterator.next();
System.out.println(a);
}
}
这样子就可以得到所有的人名啦
foreach循环不能改变集合大小
在同一个迭代器下,如果你的游标已经在最下面了,那就不能迭代了
List接口
List接口继承了父接口Collection中所有的方法,并且扩展了许多方法,它是有序的,并且List集合都有下标,下标从0开始,以递增。
List接口下有三个实现类,一个是ArrayList,一个是LinkedList,一个是Vector
ArrayList实现类
基于数组实现,连续的存储空间,查找速度快,增删速度慢,线程不安全,但是可以通过这些方法来使线程变得安全
LinkedList实现类
基于双向链表实现,分散存储,查找速度慢,增删速度快
什么叫双向链表呢?
双向链表:两头为空,中间有元素,如果要在两头加元素,那就重新创建一个,然后指向另一个元素的任意两头(自己决定),它本身就是有序的
Set接口
没有提供额外的方法,必须重写hashcode和equals
Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。
HashSet实现类
无序,不重复,线程不安全,集合元素可以是null
add()方法在调用hashCode(),决定存储位置,hashCode区分是否重复(优点:速度快。缺点:不能完全判断出内容是否相等),因此需要再调用equals方法(速度慢)判断是否重复
LinkedHashSet实现类
有序不重复
也是基于双向链表实现的,它本身是无序的,但是通过双向链表维护顺序,因此有序
TreeSet实现类
只能存储一种数据类型,可排序集合,区分重复,通过compareTo排序,用instanceof判断是不是同一种数据类型,通过返回值为0区分是否重复
排序方式需要自己定义
通过实现接口的方式进行排序就是自然排序
Comparator接口,通过实现这个接口才能对引用数据类型进行区分是否重复并进行排序(或者在类的内部实现接口)
可以改代码叫可控,不能改叫不可控。可控时自然排序,不可控时定制排序
用集合必须要使用泛型,泛型里面只能存储引用数据类型,并且该集合只能存储该数据类型的数据(除非存的是Object类型)
Map
用于保存具有映射关系的数据:Key-Value
Map 中的 key 和 value 都可以是任何引用类型的数据
无序不重复
为了保证无序不重复,因此调用hashcode和equals方法
Map 中的 key 用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法。常用String类作为Map的“键”。
put(Object key,object value)如果这个键存在,则修改值为value,如果不存在,则添加
map中没有迭代器,因此不能调用Iterator方法
key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value。
void | clear() 从此映射中移除所有映射关系(可选操作)。 |
boolean | containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。 |
boolean | containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。 |
Set<Map.Entry<K,V>> | entrySet() 返回此映射中包含的映射关系的 Set 视图。 |
boolean | equals(Object o) 比较指定的对象与此映射是否相等。 |
V | get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null 。 |
int | hashCode() 返回此映射的哈希码值。 |
boolean | isEmpty() 如果此映射未包含键-值映射关系,则返回 true。 |
Set<K> | keySet() 返回此映射中包含的键的 Set 视图。 |
V | put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)。 |
void | putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。 |
V | remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 |
int | size() 返回此映射中的键-值映射关系数。 |
Collection<V> | values() 返回此映射中包含的值的 Collection 视图。 |
这些都是用的比较多的Map的方法
Map的实现类常用的有五个:HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
HashMap
无序不重复
HashMap是 Map 接口使用频率最高的实现类。
HashMap 判断两个 key 相等的标准是:两个 key 通过 equals() 方法返回 true,hashCode 值也相等。
HashMap 判断两个 value相等的标准是:两个 value 通过 equals() 方法返回 true。
每个数据都有一个哈希值,因为这个哈希值比较大,所以通过这个哈希值%16来确定数据在集合中的位置,因此无法确定他在哪个位置,
LinkedHashMap
与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致
TreeMap
TreeMap 的 Key 的排序:
自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
Hashtable
Hashtable是个古老的 Map 实现类,线程安全。
与HashMap不同,Hashtable 不允许使用 null 作为 key 和 value
与HashMap一样,Hashtable 也不能保证其中 Key-Value 对的顺序
Hashtable判断两个key相等、两个value相等的标准,与hashMap一致。
Properties
Properties继承Hashtable,它一般放在项目的根目录中,和src平级
Collections工具类
这是一个可以操作集合的工具类,可以对集合进行增删改查
例如:
----------------------------------------------------------------------------------------------------------------------------
如果有什么错误或建议,欢迎补充