Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说《Java集合框架JCF》,希望能够帮助你!!!。
首先,我们先来大概了解一下集合,集合英文单词collection,在java属于集合框架的顶层接口,就像是容器,能储存任意数量的具有共同属性的对象。
java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包。
“集合框架”其实就是由一组用来操作对象的接口组成,不同接口描述一组不同数据类型,容器中的元素类型都为Object。从容器取得元素时,必须把它转换成原来的类型。**接口:**是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。
精华版
集合接口:6个接口(短虚线表示),表示不同集合类型,是集合框架的基础。
抽象类:5个抽象类(长虚线表示),对集合接口的部分实现。可扩展为自定义集合类。
实现类:8个实现类(实线表示),对接口的具体实现。
在很大程度上,一旦您理解了接口,您就理解了框架。虽然您总要创建接口特定的实现,但访问实际集合的方法应该限制在接口方法的使用上;因此,允许您更改基本的数据结构而不必改变其它代码。
接下来我就简单整理一下Java集合框架。
Collection接口 是Set接口 和 List接口 的父类接口
Collection接口描述:
Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于Collection的子接口(如List和Set)。
Collection接口特点:Collection 接口存储一组不唯一,无序的对象。
List接口继承自Collection接口,同时也继承了Collection接口的全部方法;
List接口描述:
List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List(列表)接口中的特点:不唯一,有序(插入顺序)的对象。
Set接口继承自Collection接口,同时也继承了Collection接口的全部方法;
Set接口描述:
Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set (集)接口特点:唯一,无序的对象
1.List接口中:元素是有序的,可以重复的。Set接口中,元素是无序的,不可以重复的;
2.List检索(查找、修改)效率高,删除和插入效率低,会引起元素位置变化。Set检索效率低,删除和插入效率高,插入和删除不会引起元素位置变化;
3.List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。
Map接口描述:
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
map<键,值>键-值对
键无序,且不能重复;
值可以重复;只能通过键来取值;
map中有一个Entry的内部接口,其实就是保存的键和值在一起的内容,整个一起的内容放到了Set集合中。
Set<Map.Entry<String,Student>> it = entry.iterator();
while(it.hasNext()){
Map.Entry<String,Student> ss = it.next();
system.out.println();
}
是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、TreeSet、HashSet、HashMap。
ArrayList<E> list = new ArrayList<E>();
ArrayList 底层基于数组的实现;
特点:
1.元素有序;
2.元素可以重复;
3.元素中可以有null元素;
4.非线性安全的;
优点:查找、修改效率高;
缺点:插入、删除效率低;
与数组的区别就是:没有确定的大小,长度可以按需求增加,底层默认赋初始值为10。
该类实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。
LinkedList<E> list = new LinkedList<E>();
基于底层双向循环链表实现的。
特点:
1.元素有顺序;
2.允许有重复的元素;
3.允许有null(空)元素;
4.非线性安全的;
优点:插入、删除效率高;
缺点:查找、修改效率低。
第一个和最后一个元素是重要的,它有个虚拟的假下标,通过第一个依次找到下一个。
链表(LinkedList)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
该类实现了List接口,主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:
List list=Collections.synchronizedList(newLinkedList(...));
该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。不常使用了。
特点:
1.线性安全的;
以下情况使用 ArrayList :
以下情况使用 LinkedList :
相同点:
ArrayList 和 Vector 都是基于数组的实现;
区别:
ArrayList 线程不安全的,效率高,在算法上做了改进;
Vector 线程安全的,目前已经不怎么使用了。
在一些底层方法上ArrayList更加优化。
HashSet是由哈希表来实现的
HashSet类描述:
该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。
HashSet特点:
1.元素没有顺序,即不会记录插入的顺序。用foreach增强for循环或迭代Iterator遍历;
2.不允许重复(比较的是哈希码);
3.允许包含null元素,但最多只能一个;
4.非线程安全的;
HashSet:内部的数据结构是哈希表,是线程不安全的。
HashSet中元素是唯一的:通过对象的hashCode()和equals()方法来完成对象的唯一性判断。
如果对象的哈希值不同,则不用判断equals方法,就直接存到HashSet中;
如果对象的哈希值相同,需要用equals方法进行比较,结果为true,则视为相同,不存,结果为false,视为不同,进行存储。
注意:如果元素要存储到HashCode中,必须覆盖hashCode方法和equals方法。
TreeSet 是依靠TreeMap来实现的
TreeSet类描述:
该类实现了Set接口,可以实现排序等功能。排序分为:自然排序和自定义排序。
TreeSet的特点:
1.元素是有序的(支持自然排序和自定义排序);
2.元素不允许重复;
3.非线程安全的;
TreeSet 中判断元素唯一性的方法,根据比较方法的返回值是否为0,如果是0,则是相同元素,不存,如果不是0,则是不同元素,存储。
TreeSet 对元素排序的方式:
默认的都是自然排序(升序排列),使用自然排序时只能在集合中加入同类型的对象,并且这些对象的类要实现Comparable接口。
元素自身具备比较功能,及自然排序,需要实现Comparable接口,并重写compareTo方法:
x.compareTo(y)–>
如果返回值为0,则表示x和y相等;
如果返回值大于0,则表示x大于y;
如果返回值小于0,则表示x小于y。
元素自身不具备比较功能,及自定义排序,则需要实现Comparator接口,并重写其compare方法:
compare(Object o1,Object o2)–>
如果o1等于o2,则返回0;
如果o1小于o2,则返回-1;
如果o1大于o2,则返回1。
注意:LinkedHashSet是一种有序的Set集合,及其元素的存入和输出的顺序是相同的。
一、实现方式
HashSet是基于哈希表实现的;
TreeSet是基于二差树实现的;
二、元素是否有序
HashSet中元素是无序的;
TreeSet中元素是自动排好序的;
三、是否可以放入null值
HashSet可以放,但只能放一个;
TreeSet不允许放。
Comparable是排序接口相当于内部比较器。是java.lang包下的,要实现compareTo方法。主要直接用于javabean的类直观实现,
实现Comparable接口的类的对象可以用作有序映射(如TreeMap)中的键或有序集合(TreeSet)中的元素,而不需要指定比较器,接口中通过重写compareTo方法比较集合中元素的大小,从而进行升序排列。
x.compareTo(y)–>
如果返回值为0,则表示x和y相等;
如果返回值大于0,则表示x大于y;
如果返回值小于0,则表示x小于y。
Comparator是比较器接口,相当与外部比较器。是java.util包下,要实现compare方法。
我们需要控制某个类的顺序,而该类本身不支持排序(即没有实现comparable接口),那么我们可以通过实现comparator类来新建一个比较器,并重写其compare方法:
compare(Object o1,Object o2)–>
如果o1等于o2,则返回0;
如果o1小于o2,则返回-1;
如果o1大于o2,则返回1。
HashMap 是基于哈希算法的Map接口实现的。
特点:
1.元素唯一的,必须重新hashCode方法和equals方法;
2.元素没有顺序;
3.非线性安全的;
4.适用于插入、删除、定位元素;
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。
HashMap总结:无序,不可重复。
为什么是无序的?因为不一定挂到哪一个单向链表上的,因此加入顺序和取出也不一样。
怎么保持不可重复?使用equals方法来保证HashMap集合key不可重复,如key重复了,value就会覆盖。存放在HashMap集合key部分的元素,其实就是存放在HashSet集合中,则HashSet集合也需要重写equals和hashCode方法。hashmap集合的默认初始化容量为16,默认加载因子为0.75,也就是说这个默认加载因子是当hashMap集合底层数组的容量达到75%时,数组就开始扩容。hashmap集合初始化容量是2的陪数,为了达到散列均匀,提高hashmap集合的存取效率
TerrMap基于红黑树算法的Map接口实现。
键存放的顺序:自然排序和自定义排序。
特点:
1.元素是有序的;
2.非线程安全的;
3.适用于按自然排序和自定义排序;
如果不需要排序首选HashMap。
想要通过键来获取值用HashMap
Collections类 用于操作集合的工具类;提供了静态方法,对集合元素进行查找、排序、修改等操作。
Arrays 类是用于操作数组的工具类;
提供了静态方法。
Collection 属于集合框架的顶层接口;
Collections 属于集合框架中的一个工具类。
Java里的泛型就是Object
定义类和接口时指定数据类型
避免发生ClassCastException异常
任何字母大写都行 一般用E或 T
遍历数组和集合框架可以采用for循环或者增强for,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或 ListIterator接口。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
迭代器,使你能够通过循环来得到或删除集合的元素。ListIterator 继承了 Iterator,以允许双向遍历列表和修改元素。
//通过iterator()方法获取迭代器对象
Iterator<Student> it = stus.iterator();
//迭代器对象循环判断有没有下一个
while(it.hasNext()) {
//获取下一个泛型对象
Student s = it.next();
System.out.println(s);
未完待续。。。。。。
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。