Java基础干货Guava集合工具CollectionUtil源码剖析
Posted 在路上的德尔菲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础干货Guava集合工具CollectionUtil源码剖析相关的知识,希望对你有一定的参考价值。
CollectionUtils
应用
public class CollectionUtilsGenTest {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>(){
{
add("duffy");
add("wang");
add("seu");
}
};
ArrayList<String> list2 = new ArrayList<String>() {
{
add("luffy");
add("wang");
add("pku");
}
};
// isNotEmpty 判断集合是否不为空,对比isEmpty 结果相反
boolean notEmpty = CollectionUtils.isNotEmpty(list1);
//---------- true -------------
// get 得到集合索引的对象
Object res = CollectionUtils.get(list1, 0);
//---------duffy ---------------
//addAll
CollectionUtils.addAll(list1,list2.iterator());
// ---list = [duffy, wang, seu, luffy, wang, pku] ---
// union 两个集合的并集
Collection union = CollectionUtils.union(list1, list2);
//----- [seu, wang, luffy, pku, duffy]-----------
// intersection 两个集合的交集
Collection intersection = CollectionUtils.intersection(list1, list2);
//--------- [wang] -------------
// isEqualCollection 判断两个集合是否相同
boolean equalCollection = CollectionUtils.isEqualCollection(list1, list2);
//----------- false ------------
}
}
public class CollectionUtilsTest {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<Integer>() {
{
add(1);
add(2);
add(3);
add(4);
}
};
//--------filter 过滤掉不符合的数据--------
CollectionUtils.filter(arrayList, o -> Integer.valueOf(o.toString()) > 4);
//-------1 -> [2,3,4] 4 -> []------
//--------select 把符合的数据重新组成一个集合,对比filter--------
Collection collection = CollectionUtils.select(arrayList, o -> Integer.valueOf(o.toString()) > 4);
//--------1-> [2,3,4] 4 -> []----------
//--------countMatch 集合中符合规则的数据个数--------
int count = CollectionUtils.countMatches(arrayList, o -> Integer.valueOf(o.toString()) > 4);
//--------1 -> 3 4 -> 0 ------------
//--------exists 集合中是否存在符合规则的数据--------
boolean exists = CollectionUtils.exists(arrayList, o -> Integer.valueOf(o.toString()) > 4);
//--------1 -> true 4 -> false-------
//--------find 注意只返回一个符合的规则数据--------
Object result = CollectionUtils.find(arrayList, o -> Integer.valueOf(o.toString()) > 4);
//--------1-> 2 4 -> null-----------
}
}
源码
isNotEmpty
public static boolean isNotEmpty(Collection coll) {
return !isEmpty(coll);
}
addAll
public static void addAll(Collection collection, Iterator iterator) {
while(iterator.hasNext()) {
collection.add(iterator.next());
}
}
public static void addAll(Collection collection, Enumeration enumeration) {
while(enumeration.hasMoreElements()) {
collection.add(enumeration.nextElement());
}
}
public static void addAll(Collection collection, Object[] elements) {
int i = 0;
for(int size = elements.length; i < size; ++i) {
collection.add(elements[i]);
}
}
Iterator
、Enumeration
、Object[]
三种类型各有各的add方式,因此需要分开写
get
public static Object get(Object object, int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
} else if (object instanceof Map) {
Map map = (Map)object;
Iterator iterator = map.entrySet().iterator();
return get(iterator, index);
} else if (object instanceof List) {
return ((List)object).get(index);
} else if (object instanceof Object[]) {
return ((Object[])((Object[])object))[index];
} else {
Iterator it;
if (object instanceof Iterator) {
it = (Iterator)object;
while(it.hasNext()) {
--index;
if (index == -1) {
return it.next();
}
it.next();
}
throw new IndexOutOfBoundsException("Entry does not exist: " + index);
} else if (object instanceof Collection) {
it = ((Collection)object).iterator();
return get(it, index);
} else if (object instanceof Enumeration) {
Enumeration it = (Enumeration)object;
while(it.hasMoreElements()) {
--index;
if (index == -1) {
return it.nextElement();
}
it.nextElement();
}
throw new IndexOutOfBoundsException("Entry does not exist: " + index);
} else if (object == null) {
throw new IllegalArgumentException("Unsupported object type: null");
} else {
try {
return Array.get(object, index);
} catch (IllegalArgumentException var4) {
throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
}
}
}
}
**考虑的很严谨,很值得学习,**其中Map类型很有意思,map.entrySet().iterator()
再进行一次get操作,和set做一样的操作;else if (object instanceof Collection)
我是没有想到:),还有IndexOutOfBoundsException
、IllegalArgumentException
异常情况需要考虑
union
public static Collection union(Collection a, Collection b) {
ArrayList list = new ArrayList();
Map mapa = getCardinalityMap(a);
Map mapb = getCardinalityMap(b);
Set elts = new HashSet(a);
elts.addAll(b);
Iterator it = elts.iterator();
while(it.hasNext()) {
Object obj = it.next();
int i = 0;
for(int m = Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; ++i) {
list.add(obj);
}
}
return list;
}
union 循环函数中为Math.max(getFreq(obj, mapa), getFreq(obj, mapb))
for(int m = Math.max(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; ++i) {
list.add(obj);
}
其中这段代码很有意思,m
取两个Collection中相同对象出现的最多次数,注意,如果比如Collection a
中有重复的,是不会去重的,只是取并集,没有单独对一个Collection中元素去重
intersection
public static Collection intersection(Collection a, Collection b) {
ArrayList list = new ArrayList();
Map mapa = getCardinalityMap(a);
Map mapb = getCardinalityMap(b);
Set elts = new HashSet(a);
elts.addAll(b);
Iterator it = elts.iterator();
while(it.hasNext()) {
Object obj = it.next();
int i = 0;
for(int m = Math.min(getFreq(obj, mapa), getFreq(obj, mapb)); i < m; ++i) {
list.add(obj);
}
}
return list;
}
intersection循环函数中为Math.min(getFreq(obj, mapa), getFreq(obj, mapb))
,m
取两个Collection中出现的最少次数,那么list也就add最少的次数,为取交集功能,同上union,并没有去重的意思。
isEqualCollection
public static boolean isEqualCollection(Collection a, Collection b) {
if (a.size() != b.size()) {
return false;
} else {
Map mapa = getCardinalityMap(a);
Map mapb = getCardinalityMap(b);
if (mapa.size() != mapb.size()) {
return false;
} else {
Iterator it = mapa.keySet().iterator();
Object obj;
do {
if (!it.hasNext()) {
return true;
}
obj = it.next();
} while(getFreq(obj, mapa) == getFreq(obj, mapb));
return false;
}
}
}
Collection.size():Returns the number of elements in this collection,map.size():Returns the number of key-value mappings in this map,如果不相同直接返回false,然后对每一个对象在Collection出现的次数是否相等,所以对Collection中顺序没有关系。比如list1[“seu”,“duffy”,“wang”,“seu”]和list2[“wang”,“seu”,“seu”,“duffy”]是isEqualCollection
返回是true的。
getCardinalityMap
public static Map getCardinalityMap(Collection coll) {
Map count = new HashMap();
Iterator it = coll.iterator();
while(it.hasNext()) {
Object obj = it.next();
Integer c = (Integer)((Integer)count.get(obj));
if (c == null) {
count.put(obj, INTEGER_ONE);
} else {
count.put(obj, new Integer(c + 1));
}
}
return count;
}
Cardinality翻译为基数,这个逻辑经常在HashMap的逻辑中看到,统计相同的key出现的次数,然后返回这样一个map。
getFreq
private static final int getFreq(Object obj, Map freqMap) {
Integer count = (Integer)freqMap.get(obj);
return count != null ? count : 0;
}
取getCardinalityMap
中key对应出现的次数。
filter
public static void filter(Collection collection, Predicate predicate) {
if (collection != null && predicate != null) {
Iterator it = collection.iterator();
while(it.hasNext()) {
if (!predicate.evaluate(it.next())) {
it.remove();
}
}
}
}
select
public static Collection select(Collection inputCollection, Predicate predicate) {
ArrayList answer = new ArrayList(inputCollection.size());
select(inputCollection, predicate, answer);
return answer;
}
public static void select(Collection inputCollection, Predicate predicate, Collection outputCollection) {
if (inputCollection != null && predicate != null) {
Iterator iter = inputCollection.iterator();
while(iter.hasNext()) {
Object item = iter.next();
if (predicate.evaluate(item)) {
outputCollection.add(item);
}
}
}
}
countMatches
public static int countMatches(Collection inputCollection, Predicate predicate) {
int count = 0;
if (inputCollection != null && predicate != null) {
Iterator it = inputCollection.iterator();
while(it.hasNext()) {
if (predicate.evaluate(it.next())) {
++count;
}
}
}
return count;
}
exists
public static boolean exists(Collection collection, Predicate predicate) {
if (collection != null && predicate != null) {
Iterator it = collection.iterator();
while(it.hasNext()) {
if (predicate.evaluate(it.next())) {
return true;
}
}
}
return false;
}
find
public static Object find(Collection collection, Predicate predicate) {
if (collection != null && predicate != null) {
Iterator iter = collection.iterator();
while以上是关于Java基础干货Guava集合工具CollectionUtil源码剖析的主要内容,如果未能解决你的问题,请参考以下文章
Java基础干货Guava CacheBuilder源码剖析
别再重复造轮子了,推荐使用 Google Guava 开源工具类库,真心强大!
有没有一种优雅的方法可以在使用 Guava 转换集合时删除空值?
集合-强大的集合工具类:java.util.Collections中未包含的集合工具