集合

Java集合大致可以分为set、List、Queue、和Map四种体系,其中set代表无序不可重复的集合;List代表有序、可重复的集合;Map代表具有映射关系的集合;Jdk5增加的Queue体系集合代表一种队列集合的实现。

这里写图片描述
数组可以存放基本数据类型和对象,但是集合只能保存对象(引用)(Java支持自动装箱)。

Set集合类似一个罐子,把一个对象添加到Set集合时,无法记住添加顺序,所以元素不能重复;List集合像一个数组,它可以记住每次添加元素的顺序、且List的长度可变;Map也像一个罐子,只是它里面的每项数据都由key和value组成。所以,访问Set集合中的元素,只能通过元素本身来访问;List可以通过元素的索引;Map通过key来访问value。

Map没有实现Collection接口
这里写图片描述

Iterable接口是Collection接口的父接口

Iterator接口也是集合框架的成员,但与Collection和Map系列的集合不一样,后两者用来盛放对象,而前者主要用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。

Iterator接口定义了四种方法:boolean hasNext():是否遍历完 Object next():返回集合里的下一个元素 void remove():删除上一次next方法返回的元素 void forEachReamining(Comsumer action):Java8为Iterator新增的默认方法,可使用Lambda表达式遍历集合元素。
迭代器依赖于Collection对象,Iterator并不是把集合元素本身传给了迭代变量,而是集合元素把元素的值传给了迭代变量,所以修改迭代变量的值不会对集合元素产生影响。
在使用迭代器访问Collection集合元素时,Collection元素里的元素不能被改变,只有通过迭代器的remove方法删除。否则抛出java.util.ConcurrentModficationException异常。迭代器采用的是快速失败机制,一旦检测到该集合已经被修改(通过其他线程),就会抛出异常,而不会显示修改后的结果,这样可以避免共享资源而引发的潜在问题。

另外也可以通过foreach循环来迭代访问Collection集合里的元素。也是只是把集合元素赋值给迭代变量,访问期间集合也不能被改变,也会抛异常。

Set:

HashSet类:

按照Hash算法存储集合中的元素,具有的特点:不能保证元素顺序;不是线程安全的;集合元素值允许为null。
当存入一个对象时,HashSet会调用对象的hashCode()方法得到该对象的hashCode值,然后根据hashCode值决定该对象在HashSet中的存储位置。hashCode值不同,equals()返回值为true,判定为不同对象,存放在不同位置(根据hashCode决定);hashCode值相同,equals为false,判定为不同对象,会在该位置上用链式结构保存多个对象,会导致性能下降。因此当hashCode值相同时,equals应该返回true。 只有当hashCode相同且equals返回值为true才会认为是同一对象。
当向HashSet集合添加元素时,HashSet会根据该元素的hashCode来计算它的存储位置,访问时,HashSet先计算该元素的hsahCode值,然后直接到该hashCode对应的位置取出该元素。这就是HashSet速度很快的原因。

LinkedHashSet:

HashSet的子类,也是根据hashCode值决定元素的存放位置,但他同时使用链表维护元素的次序。不是线程安全的。
元素看起来是以插入的顺序保存的,当遍历其元素时,LinkedHashSet将会按照元素的添加顺序来访问集合的元素。性能降低,但在迭代访问Set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。输出的元素顺序总是与添加顺序一致,但依然是HashSet,并不允许元素重复。

TreeSet类:

是SortedSet接口的实现类。可以确保集合元素处于排序状态。采用红黑树的数据结构来存储集合元素。不是线程安全的。TreeSet支持两种排序方法。
自然排序(Comparable):TreeSet会调用集合元素的comparTo方法来比较元素之间的大小关系,然后将元素按升序排列。obj1.compareTo(obj2)的返回值-1(负整数),0,1(正整数)分别对应小于,等于,大于(相等时新对象无法添加到TreeSet集合中)。如果试图将一个对象添加到TreeSet中时,该对象的类必须实现Comparable接口,否则抛出ClassCastException异常(添加第一个元素时可以不实现Comparable接口,后面的必须实现,但当取值时依然抛出ClassCastException)。 (同一种类型元素的比较,这就要求向TreeSet添加的应该是同一个类的对象,否则也会抛出类型异常;实现了compareTo且没有类型强转的自定义类型不同对象在添加时不会报错,但取值时依然抛异常)
实现Comparable接口,重写compareTo方法,同时重写equals方法。当compareTo返回0但equals返回false时,TreeSet不会让第二个元素添加进去,这就与Set集合的规则产生冲突。
TreeSet可以删除没有被修改的实例变量、且不与其他被修改实例变量的对象重复的对象。一旦改变了TreeSet集合里可变元素的实例变量,修改会失败(甚至与修改后的元素相等的元素也不能修改)。
定制排序(Comparator):需要在创建TreeSet集合对象时,提供一个Comparator对象与该TreeSet集合关联,由该Comparator对象负责集合元素的排序逻辑。(不需要修改bean类,较具有实用性)由于Comparator是一个函数式接口,因此可以使用Lambda表达式来代替Comparator对象。
依然不可以添加不同类型对象,此时判断两个对象的标准是通过Comparator比较两个元素返回了0,这样就不会把第二个元素添加到集合中。

EnumSet类:

专门为枚举类型设计的集合类,所有类型必须是指定枚举类型的枚举值(创建时显示或隐式指定)。不是线程安全的。元素有序,以枚举值在Enum类内定义顺序。在内部以向量的形式存储,占用空间少且运行效率高,速度快。不允许插入null值会抛出空指针异常。
没有提供构造器来创建EnumSet对象。当试图复制一个Collection集合里的元素来创建EnumSet集合时,必须保证Collection集合里的所有元素都是同一个枚举类的枚举值。

比较:HashSet性能比TreeSet好,当需要一个保持排序的Set时,才会使用TreeSet。LinkedHashSet比HashSet略慢(插入删除),但有了链表,遍历LinkedHashSet会更快。

List集合:

list代表一个元素有序、可重复的集合,每个元素都有其对应的顺序索引。允许重复元素,可通过索引访问指定位置集合元素(从0开始)。
Java8中为List集合添加了sort()和replaceAll()两个常用默认方法,其中sort方法需要一个Comparator对象类控制元素排序。而replaceAll需要一个UnaryOperator(函数式接口)来替换所有集合元素。
List还额外提供了一个listIterator()方法,返回一个listIterator对象。ListIterator接口继承了Iterator接口,提供了专门操作List的方法,在Iterator接口基础上增加了如下方法:boolean hasPreious():是否还有上一个元素 Object Previous():返回迭代器的上一个元素 void add(Object o):在指定位置插入一个元素 它增加了向前迭代的功能。而且还可以添加元素(Iterator只能删除)。

ArrayList和Vector:

前者出现于后者之后,先出现者线程安全,后出现者线程不安全。

LinkedList类:

可以根据索引来随机访问集合中的元素。实现了Deque接口,可以被当作双端队列来使用,既可以作为队列使用,也可以作为栈使用。

总结:数组以一块连续内存区来保存所有的数组元素,所以数组随机访问性能最好,所有内部以数组为底层实现的集合在随机访问时性能都比较好;而内部以链表为底层实现的集合在执行插入、删除操作时有较好性能。

Queue集合:模拟队列这种数据结构,先进先出。

Map集合:

保存具有映射关系的数据,保存着key和value两组值。key和value都是任何引用类型的数据。key唯一,通过equals方法比较的两个key总是返回false。(允许多对一)。keySet()用于返回Map里所有key组成的set集合。Map提供了一个entry内部类来封装key-value对。java是先实现了Map,然后通过包装一个所有value都为null的Map就实现了Set集合。 value类似于list。

HashMap和Hashtable实现类:

类似于ArrayList和Vector的关系。后者线程安全。HashMap允许使用最多一个null作为key或多个null的value。Hashtable不允许(空指针异常)。
由于key实际上是一个set集合,所以用作key的对象不必须实现hashCode和equals方法。 包含一个containsValue()方法,用于判断是否包含指定vaule,通过equals判断。

SortedMap接口:

派生自Map接口(类似于Set接口派生出SortedSet),

TreeMap类:

红黑树结构,每一个key-value对作为红黑树的一个节点。存储时通过key对节点进行排序。也有两种排序方式(针对key):自然排序和定制排序(与TreeSet十分类似)。set和map关系十分紧密,java源码先实现了HashMap、TreeMap等集合,然后包装一个所有value为null的map集合实现了Set集合类。

WeakHashMap类:

与HashMap基本类似,区别在于:HashMap的key保留了对实际对象的强引用,这意味着只要该Hashmap对象不被销毁,所有的key所引用的对象就不会回收,也不会自动删除对应的value。但WeakHashMap的key是对实际对象的弱引用。当key没有被其他强引用变量所引用,key可能会被回收,WeakHashMap也可能自动删除这些key所对应的key-value对。

IdentityHashMap类:

与HashMap基本类似,只是它使用==而不是equals来判断元素相等。

EnumMap类:

枚举,key必须是单个枚举类的枚举值(EnumSet)。

操作集合的工具类:Collections,提供大量方法对集合元素进行排序、查询和修改等操作。还提供了将集合对象设置为不可变、对集合对象实现同步控制等方法。

泛型:将数据类型参数化,在编译时阻止用户非法输入,减少运行时抛出的ClassCastException,设计原则:只要代码在编译期没有出现警告,就不会遇到运行时ClassCastException.
擦除:允许在使用带泛型声明的类时 不指定实际的类型参数,此时该类型参数被称为raw type原始类型,默认是 声明该类型参数时指定的第一个上限类型。当把一个具有泛型信息的对象赋值给另一个没有泛型信息的变量时,所有在<>之间的类型信息都将被扔掉。即为类型擦除。

T : type
E : Element
K : Key
V : Value

泛型定义语法:<TypeVar>

1.泛型接口:
    public interface InterName<T>{
    }
2.泛型类:
    public class className<T>{
    }
3.
    public class clsName<E extends Number> implements InterName<E>{

    }

Note:
    1.泛型类型不能被实例化
    2.泛型是编译时行为,会自动擦除为上限类型。
        ArrayList list = new ArrayList();
        ArrayList list2 = new ArrayList<String>();
        ArrayList<String> list3 = new ArrayList<String>();
        ArrayList<String> list4 = new ArrayList();
    后两种有效。
    3.泛型类型只能是类类型,不能是基本数据类型。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值