java集合 读书笔记

Java库中的具体集合和整个集合框架

链表

数组列表

散列集

树集

队列与双端队列

优先级队列

映射表

 

Java库中的具体集合和整个集合框架

 

  链表(LinkedList)

数据和数组列表有一个重大缺陷,因为删除一个或者添加一个元素都需要付出很大的代价,原因是出于被删除或被添加的元素后面的所有元素都要被移动,而链表就解决了这个问题。删除添加只需要对被删除元素附近的节点更新一下即可。但因为结果原因,如果要对集合经常随机访问,则最好使用arraylist.

 

LinkedList.add方法是把元素添加到尾部,如果想添加到中间,就的借助迭代器。因为linkedlist里面的元素是有序的,所以他的迭代器里面是有添加方法的,而集(set)里面的元素完全无序,所以他的迭代器接口就没有add方法。ListIterator里面的add方法就可以把元素添加到迭代器位置之前。。

 

如果有多个迭代器在一个集合上迭代,集合被一个迭代器或者自身修改,那么迭代器都没有意义了,就会发出异常!

 

列表不支持快速随机访问,如果想访问第N个元素,那就就的才能够头开始越过n-1个元素,所以在这种情况下一般不选择链表。但是尽管如此LinkedListjava类库还是提供了理论上存在争议的一些方法。比如采用整数索引访问元素,get(n)但是这个效率肯定不高,previousIndex,nextIndex这个效率还是很高的。

 

数组列表(ArrayList)

ArrayList实现了list接口,而且对于get,set方法随机访问每个元素是非常的效率,封装了一个动态再分配的对象数组。

 

散列集(hashSet)

散列码由hashcode方法生成,应该于equals方法兼容,就是说如果a.equals(b)为true,那么a,b的散列码一定相同,如果自己定义类就应该负责实现这个类的hashCode方法。里面的元素是没有顺序的,而且元素不能重复。迭代器也是随机的遍历元素。

 

 

数集(treeSet)

与散列集不同的是,添加完元素后,元素会按照树结构把元素自动有序的排列起来,这样便利的时候得到的是已经排好序列的元素列表。当然添加元素的速度要比散列集慢点,但是还是比链表和数组的正确位置上要快点。

队列与双端队列

队列java.util.Queue 双头队列java.util.Deque可以在头部或尾部添加删除元素。

优先级队列(priority queue)

元素可以随便插入队列。也就是说remove的时候一定是优先级最小的元素。优先级队列使用了一个优雅且高效的数据结构堆(heap),这是一个可以自我调整的二叉树,添加删除操作,可以让最小的元素移动到跟。举个例子更好的了解,他不是把全部元素排序,而是只是把最小的放在的最头上面。TreeSet却是把全部排序,所以优先级队列速度要比treeset快。

 

结果

Iterating over elements...
1815
1906
1903
1910
Removing elements...
1815
1903
1906
1910

映射表(hashMap TreeMap)

散列映射对键进行散列,而树映射表用键的整体顺序对元素进行排列,只作用于键,对关联的值不能进行散列和比较。这里有3个试图,键集,值集合,键值对集。

  • Set<K> keySet()
  • Collection<V> values()
  • Set<Map.Entry<K,V>> entrySet()

for(String key:keys)//遍历键集

{

do something with key

 }

//遍历对集

for(Map.Entry<String,Employee> emtry : staff-emtrySet()){

String key=entry.getKey();

Employee value= entry.getValue();

do something with key,value

}

专业集与映射表类

弱散列映射表(weakHashMap)

有些值的键被引用一次后就不用了如果不明确的删除,垃圾收集器收集器又不会自动收集垃圾,所以就用到了弱散列映射表。

 

链接散列集和链接映射表(linkedhashset,linkedhashmap)

这样就能记住插入元素项的顺序。遍历的时候就能按照插入的顺序遍历。 当然也可以按照存取顺序遍历,当用get or put方法,那么这个被取出或者放进去的元素就会被从当前位置去掉,然后放到最后面。这样有利于实施一个 最近最少使用的cache。

 

枚举集与枚举映射集(EnumSet,EnumMap)

EnumSet是一个枚举类型元素集的高效实现。 由于枚举类型只有有限个实例, 所以EnumSet内部用位序实现,如果对应的值集中,则相应的位置为1.

enum Weekday {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY};

      EnumSet<Weekday> always = EnumSet.allOf(Weekday.class);
      EnumSet<Weekday> never = EnumSet.noneOf(Weekday.class);
      EnumSet<Weekday> workday= EnumSet.range(Weekday.MONDAY, Weekday.FRIDAY);
      EnumSet<Weekday> mwf = EnumSet.of(Weekday.MONDAY, Weekday.WEDNESDAY, Weekday.FRIDAY);

 

EnumMap

EnumMap<Weekday,Employee> personInCharge = new EnumMap<Weekday, Employee>(Weekday.class);

 

标识散列映射表(IdentityHashMap)

键的散列值不是用hashcode计算的,而是用System.identityHashCode计算的,这是object.hashCode方法根据对象的内存地址来计算散列码时用的方式。对两个对象进行比较时,不用equals,而是==。也就是说不同的键对象,即使内容相同,也被视为不同的对象。

 

视图与包装器

Arrays类的静态方法asList将返回一个包装了普通java数组的list包装器。

Card[] cardDeck = new Card[52];

List<Card> cardList = Arrays.asList(cardDeck);

这是个视图对象,可以使用get,set方法,但是添加删除都会抛出异常。

 

Collections.nCopies(n,anObject)创建一个包含n个元素的list,每个元素都是一个anObject.

Collections.singleton(anObject)返回一个视图对象,实现了set接口,不可修改的单元素集。

 

subList(),subSet,headSet,tailSet,subMap,headMap,tailMap方法可以得到相应集合的子范围,而且子范围上的修改直接反应到原集合上。

 

Collections.unmodifiableCollection,Collections.unmodifiableList,Collections.unmodifiableSet,Collections.unmodifiableSortedSet,

Collections.unmodifiableMap,Collections.unmodifiableSortedMap可以得到不可更改视图,只能读不能修改。但是原集合依然可以修改。

 

Collections.synchronizedMap可以得到线程安全的同步视图,这样就可以多线程访问同步视图了,get,put这种操作都被串行操作,是线程安全的。

 

被检查视图可以检测是否有classCast错误例子如下:

 

这里还有一些批操作

 

Set<String> result=new HashSet<String>(a);

result.retainAll(b)在result保留a与b中出现的元素。就是交集。

 

removeAll,allAll

 

集合与数组之间的转化

String[] values = ...;

HashSet<String> staff= new HashSet<String>(Arrays.asList(values));

 

String[] values = staff.toArray(new String[staff.size()]);

 

算法

Collections.sort(staff,itemComparator);

Collections.sort(staff,Collections.reverseOrder(itemComparator));

Collections.schuffle(ArrayList);随机混排列表里面的元素。

Collecitions.binarySearch(c,element),Collections.binarySearch(c,element,comparator);但是前提是集合必须是有序的而且是支持随机访问的。否则不是有序的就出异常,不是随机访问的,效率非常低就跟线性查找一样的效率了,如果找不到对应元素,那么可以根据范围的负值索引,插入这个元素,if(i<0) c.add(-i-1,element); i是返回的负值索引。

min,max,copy,fill,addAll,indexOfSubList,lastIdexOfSubList,swap,reverse,rotate,frequency,disjoint方法。

遗留的集合

hashTable跟hashMap作用一样,而且是同步的,但是如果对同步性或者与遗留代码的兼容性没有任何要求,就应该使用hashMap.

 

枚举Enumeration有两个方法,hasMoreElements,nextElement类似与iterator接口的hasNext,next方法。

 

属性映射表(perperty map)比较特殊,有3个特性:键与值都是字符串,可以保存到一个文件中,也可以从文件中加载。还有一个默认的辅助表。

 

位集(BitSet)用来存放一个位序列,由于位集将位包装在字节里面,所以比使用Boolean对象的ArrayList更加有效。

 

 

 

 














 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值