类集部分总结

集合框架的组成部分:
Collection:集合类的最顶层的父接口,定义了存取对象的一组方法,它的子接口List和Set分别定义了存储方式;
List:元素加载和移除时按照顺序进行,元素按升序排列。
Set:元素不能有重复,没有次序。
SortedSet:与Set接口相同,但是按照升序排列;
Map:Map不继承Collection,以键值对的形式存储元素,无存放顺序,key不能重复,value可以重复。
List接口下有ArrayList、Vector、LinkedList
Map接口下有HashMap、TreeMap
Set接口下有HashSet
SortedSet接口下有TreeSet
Hashtable继承自Dictionary,不是Map的实现子类

ArrayList与LinkedList还有Vector的关系
相同点:三者都是List接口下的实现类;ArrayList与Vector底层都是用数组实现的,LinkedList是基于链表实现的。
不同点
1)ArrayList采用懒加载模式,在第一次添加元素时开始初始化数组,初始化大小为10;扩容策略是扩容为原来的数组长度的1.5倍;线程不安全,效率较高。
2)Vactor在创建对象时就进行初始化,初始化大小为10;扩容策略是扩容为原来数组的2倍;采用synchronized同步锁来保证线程安全,效率较低。
3)LinkedList底层是链表实现的,异步实现,线程不安全,效率较低
使用场景:频繁的进行查询操作使用ArrayList,频繁地在任意位置进行插入和删除操作使用LinkedList,尽量不要使用vector。

jcl下的fail-fast以及fail-safe
fail-fast快速失败策略:优先考虑异常情况,出现异常则抛出异常,程序终止。
发生场景:使用迭代器输出集合重元素进行修改的时候。
java.util.ConcurrentModificationException
产生ConcurrentModificationException原因?
remove():删除列表中指定位置的元素(可选操作)。将任何后续元素向左移位(减去一个元素来自他们的指数),返回从中删除的元素清单。后序元素向左移动的话,就会出现下表溢出异常,从而引发并发修改异常
modCount != expectedModCount
modCount:记录当前集合修改次数
expectedModCount:是一个副本,记录当前集合获取迭代器修改次数
解决fail-fast:
1)使用迭代器内部删除:iterator.remove(),但是使用iterator虽然实现了删除元素,由于打印操作在循环内部,在内部打印还是会输出删除的元素。
2)遍历集合的时候不要修改,或者创建一个新的list来接收
3)使用fail-safe集合;juc包的集合(ConcurrentHashMap、CopyOnWriteArrayList)都是fail-safe;
在java.util包下除了TreeMap都是fail-fast.

List、Set与Map的关系:
相同点:Set底层用的是相同算法的Map;在Map中所有的key就是一个Set集合;List和Set是Collection的子接口(Map和Collection是平级的)
不同点
1)Set的结点是一个数据;Set存储已排序的无重复元素,若多次插入相同元素,只显示一个。
2)Map的节点是一对数据,以K-V键值对的方式存储元素;Map使用关键字key来唯一标识每一个成员,Map中的value可以重复。
3)List允许有重复的元素,任何数量的重复元素都可以在不影响现有重复元素的值及其索引的情况下插入到List集合中。

TreeMap、HashMap与Hashtable的关系
相同点:都是Map集合的子类
不同点
1)HashMap底层使用hash表+红黑树;key值和value值都可以为null,但是key值只能有一个为null,key值不能重复;异步实现,线程不安全,效率较高
2)Hashtable底层基于hash表;key值和value值都不能为null;线程同步,使用一把锁锁住的是整张表,效率较低
3)TreeMap底层基于红黑树;key值要进行比较,不能为null但是value可以为null;异步实现,线程不安全,效率较高

Java中实现一个类的两个对象进行比较的操作有内部排序和外部排序
内部排序(Comparable):这个类实现了comparable接口,重写其中的compareTo(),具备天然可比较的能力。单例模式的类不能进行排序。
外部排序(Comparator):将比较器的实现放在了类的外面,在外面定义了一个比较器类。新定义一个类,这个类必须实现Comparator接口,重写compare方法。
使用场景(如何选择)
1.当我们自定义一个类的时候,使用内部比较器,他比较符合Java封装的特点,但是由于我们用到的类常常不是我们自定义的,我们只能调用的时候,就要使用外部比较器。
2.有时候我们用内置的类,但这个类本身恰好实现了内部比较器(如基本类型的封装类、String、Date),但是他定义的比较方式不是我们想要的(比如,Integer内部比较器的实现是按照数字大小进行排序,但是当我们想要按照绝对值大小进行排序时)这时候就要用到外部比较器。
3.有时候按照对象的不同属性进行排序,就需要定义多个外部比较器来实现。

hashcode()与equals()的关系
hashcode相等的不一定是同一个对象,equals不一定为true(可能会产生哈希碰撞导致两个对象的hashcode值相等);但是equals为true则hashcode一定相等因为equals方法返回true则代表是一个对象,如果equals为true但是hashcode不相等则违背了Object.hashCode中的通用约定:相等的对象必须有相同的散列码,对于HashMap和HashSet这些基于hash实现的类,数组的下标是根据传入元素的返回值和特定的值通过亦或操作决定的,如果覆写了equals方法而不覆写hashcode方法的话,可能导致HashSet、HashMap不能正常的运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值