携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
集合工具类
许多开源机构为我们提供了操作集合的工具类。
apache
Apache.commons下的commons-collectionsX包对java集合框架(java collection framework)做扩展。
- Bag - 简化了一个对象在集合中存在多个副本的操作
- BidiMap - 提供双向映射,可通过键查找值,也可以通过值查找键
- Iterators - 方便迭代
Bag
Bag
简化了一个对象存在多个副本的操作。
HashBag & TreeBag
hashBag & TreeBag的继承关系如下图所示:
TreeBag 相较于HashBag多实现一个接口 : SortedBag即表现为一个有序的bag。
HashBag其内封装了一个HashMap,key是元素,value是元素个数。
TreeMap其内封装了一个TreeMap,key是元素,value是元素个数。
hashBag&TreeBag的创建。
public HashBag() {
super(new HashMap<E, MutableInteger>());
}
public HashBag(final Collection<? extends E> coll) {
this();
addAll(coll);
}
private transient Map<E, MutableInteger> map;
protected AbstractMapBag(final Map<E, MutableInteger> map) {
super();
this.map = map;
}
hashBag&TreeBag基本使用3
/**
* hashBag底层是一个hashMap 元素是key值,添加个数是value
* 可以通过add(object,nCopies)方法为每个元素添加n个副本
* 如果add两次则会跟新value值(加一)
*/
StringBuilder sb1 = new StringBuilder("a");
StringBuilder sb2 = new StringBuilder("b");
StringBuilder sb3 = new StringBuilder("c");
Bag<Object> hashBag = new HashBag<>();
hashBag.add(sb1);
hashBag.add(sb1);
hashBag.add(sb2, 3);
hashBag.add(sb3, 3);
System.out.println("Bag+元素个数:" + hashBag.size());
System.out.println("Bag中sb1个数:" + hashBag.getCount(sb1));
String result1 = hashBag.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("HashBag 内容:" + result1);
//可以使用Collection作为构造方法参数
Bag<Object> hashBag2 = new HashBag<>(Arrays.asList("1", "2", "3"));
String result3 = hashBag2.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("hashBag2 内容:" + result3);
/**
* TreeBag:底层封装了一个TreeMap。
* 其实可依发现HashBag中的元素是无序的,那么TreeBag就是一个有序的Bag
*/
TreeBag<String> treeBag = new TreeBag<>(Arrays.asList("99", "2", "3", "7"));
String result2 = treeBag.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("TreeBag 内容:" + result2);
CollectionBag
CollectionBag
没有无参构造,必须依赖一个Bag
类型的参数。CollectionBag
只是对Bag
的封装,任何操作实际上操作的是封装的Bag。
/**
* CollectionBag的创建依赖于现有Bag,不可使用Collection作为构造方法参数
*
* 其内方法是对Bag的一层封装,实际调用的还是Bag的方法
*/
Bag<Object> collectionBag = CollectionBag.collectionBag(hashBag);
String result4 = collectionBag.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("CollectionBag的内容:" + result4);
Bag<Object> collectionBag2 = CollectionBag.collectionBag(treeBag);
String result5 = collectionBag2.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("CollectionBag2的内容:" + result5);
PredicatedBag & PredicatedSortedBag
PredicatedBag
的构造器依赖一个现有Bag和一个Predicate
,可以对加入进来的元素进行限制,比如不允许添加空元素。
/**
* 创建PredicatedBag也依赖一个现有Bag,以及一个‘判断器’
*/
PredicatedBag<Object> predicatedBag = PredicatedBag.predicatedBag(collectionBag, Objects::nonNull);
String result6 = predicatedBag.stream().map(Object::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("predicatedBag的内容:" + result6);
SynchronizedBag & SynchronizedSortedBag
/**
* SynchronizedBag同步的bag,使用Synchronized同步代码块实现同步。
* 可以指定锁对象,如果不指定则锁this
*/
SynchronizedBag<Object> synchronizedBag = SynchronizedBag.synchronizedBag(collectionBag);
SynchronizedSortedBag<Object> synchronizedSortedBag = SynchronizedSortedBag.synchronizedSortedBag(treeBag);
TransformedBag
对原集合进行转化,一般不会用这个,java8提供的
Stream API
有一个Map方法,可以将结果映射。
- transformingBag 方法,只会对后面add进来的元素进行转换,而对之前的初始化的不会转化
- transformedBag方法,会对后加的以及一开始初始化的都进行转化
/**
* TransformedBag
*/
Bag<Object> bag1 = TransformedBag.transformingBag(hashBag, Object::hashCode);
bag1.add("XX", 3);
String result8 = bag1.stream().map(Objects::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("TransformedBag.transformingBag " + result8);
Bag<Object> bag2 = TransformedBag.transformedBag(hashBag, Object::hashCode);
bag2.add("xx",3);
String result9 = bag2.stream().map(Objects::toString).collect(Collectors.joining(",", "[", "]"));
System.out.println("TransformedBag.transformingBag " + result9);
UnmodifiableBag
不可修改的Bag。
BagUtils
协助生成bag,其实调用的就是
XXXBag.xxxBag()
方法,每一个Bag类都会有一个静态方法,用于生成Bag。
/**
* BagUtils Bag工具类 协助生成Bag
*/
final Bag<Object> bag = BagUtils.collectionBag(new HashBag<>());
BidiMap
BidiMap - 提供双向映射,可通过键查找值,也可以通过值查找键
DualHashBidiMap
双重hashMap。其内封装了两个hashMap,bidimap的put()方法中key-value有任意重复的此条记录会被覆盖
/**
* bidimap
* - bidimap的put()方法中key-value有任意重复的此条记录会被覆盖
*/
@Test
public void testBidiMap() {
final DualHashBidiMap<String, Integer> dualHashBidiMap = new DualHashBidiMap<>();
dualHashBidiMap.put("a", 1);
dualHashBidiMap.put("b", 2);
dualHashBidiMap.put("c", 3);
dualHashBidiMap.put("d", 3);
dualHashBidiMap.put("e", 12);
dualHashBidiMap.put("e", 123);
System.out.println(dualHashBidiMap.get("a"));
System.out.println(dualHashBidiMap.getKey(1));
System.out.println(dualHashBidiMap.getKey(3));
System.out.println(dualHashBidiMap.values());
System.out.println(dualHashBidiMap.keySet());
}```
```bash
1
a
d
[1, 2, 3, 123]
[a, b, d, e]
erators
iterators
提供了许多迭代包装类使我们很容易迭代集合,并且支持逆向迭代
ArrayItertor
数组迭代器,接收一个数组、迭代起始下标、迭代终止下标。
只接受迭代数组,因为next()方法会调用,本地静态方法
Array.get(array,index)
ArrayListIterator
接收一个数组,起始下标,终止下标。
对
ArrayIterator
的拓展,支持正向迭代、也支持反向迭代。
public static native Object get(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
简单使用
/**
* ArrayIterator 数组迭代器,接受一个数组、起始下标、终止下标
*/
Iterator<Object> arrayIterator1 = new ArrayIterator<>(Arrays.asList("1", "2", "3").toArray(),0,2);
while (arrayIterator1.hasNext()) {
System.out.println(arrayIterator1.next());
}
ArrayListIterator
接收一个数组,起始下标,终止下标。
对
ArrayIterator
的拓展,支持正向迭代、也支持反向迭代。
/**
* ArrayListIterator
* 支持正向迭代、逆向迭代
*/
ArrayListIterator<Object> arrayListIterator2 = new ArrayListIterator<>(Arrays.asList("1", "2", "3","4", "5", "6").toArray(), 2, 6);
while (arrayListIterator2.hasNext()) {
System.out.println(arrayListIterator2.next());
}
while (arrayListIterator2.hasPrevious()) {
System.out.println(arrayListIterator2.previous());
}
BoundedIterator
有边界的迭代器,接收三个参数
Iterator
迭代器、offeset
偏移量、max
迭代数量。如下表示从下标2开始、迭代2个元素,结果是 3、4
List<String> list = Arrays.asList("1", "2", "3", "4", "5");
BoundedIterator<String> boundedIterator = new BoundedIterator<>(list.iterator(), 2, 2);
while (boundedIterator.hasNext()) {
System.out.println(boundedIterator.next());
}