Guava - 强大的集合工具Iterables
一、简介
Guava
提供了一些java.util.Collections
中没有提供的关于Iterable的公共操作,
而这些操作都封装在了工具类 - Iterables
中.
为什么提供了Iterables
?
只要可能,Guava
更愿意提供实用的工具类来接受Iterable
而不是Collection
.
Iterable
实际并不存储在主内存中,并且在不实际获取所有元素的情况下无法支持size()
之类的操作。
因此,可以在Iterables
中找到许多我们可能希望看到的支持所有集合的操作。
Iterables
类中的绝大多数操作都是惰性的:它们只在绝对必要的时候才推进支持迭代。本身返回Iterables
的方法将返回延迟计算的视图,而不是显式地在内存中构造一个集合.
二、常用方法
1、合并方法 - concat()
Iterables
提供了将多个Iterable<? extends T>
合并为一个Iterable<T>
的方法.
它会将传入的一个或者多个Iterable<? extends T>
连接起来并且返回一个延时的视图.
实验代码:
List<Integer> list1 = Lists.newArrayListWithCapacity(0);
list1.add(null);
list1.add(1);
list1.add(2);
List<Integer> list2 = Lists.newArrayListWithCapacity(0);
list2.add(2);
list2.add(3);
list2.add(4);
Iterable<Integer> testIterable = Iterables.concat(list1, list2);
System.out.println("==========测试concat()方法===================" + testIterable);
实验结果:
==========测试concat()方法===================[null, 1, 2, 2, 3, 4]
2、统计对象频率方法 - frequency()
Iterables
的frequency()
可以统计出指定的对象在Iterable
中出现的次数
实验代码:
System.out.println("==========测试concat()方法===================" + testIterable);
//测试iterables对象出现次数方法
System.out.println("==========测试frequency()方法===================" + Iterables.frequency(testIterable, 1));
System.out.println("==========测试frequency()方法===================" + Iterables.frequency(testIterable, 11));
实验结果:
==========测试concat()方法===================[null, 1, 2, 2, 3, 4]
==========测试frequency()方法===================1
==========测试frequency()方法===================0
通过源码以及实验结果表明,当存在指定对象时,返回指定对象的出现次数,如果指定对象不存在,返回0.
3、分区方法 - partition()
Iterables
提供了对指定Iterable<T>
通过指定分区大小进行分区.并返回Iterable<List<T>>
.
需要注意的是:Iterable
不能为NULL
并且指定的分区大小必须大于0.
实验代码:
System.out.println("==========测试concat()方法===================" + testIterable);
//测试partition方法
System.out.println("==========测试partition()方法===================" + Iterables.partition(testIterable, 2));
实验结果:
==========测试concat()方法===================[null, 1, 2, 2, 3, 4]
==========测试partition()方法===================[[null, 1], [2, 2], [3, 4]]
可以发现Iterable
中的元素已经变为了List
节点
4、获取首个节点方法 - getFirst()
Iterables
的IgetFirst(Iterable<? extends T> iterable, @Nullable T defaultValue)
方法可以获取指定迭代器的首位节点,如果Iterable
为空,则返回指定的defaultValue
.
实验代码:
//测试getFirst方法 - 如果为空将返回设定的默认值
System.out.println("==========测试iterable不为空 - getFirst()方法===================" + Iterables.getFirst(testIterable, 2));
System.out.println("==========测试iterable为空 - getFirst()方法==================" + Iterables.getFirst(testIterable1, 2));
System.out.println("==========测试iterable为空 - getFirst()方法==================" + Iterables.getFirst(testIterable1, null));
实验代码:
==========测试iterable不为空 - getFirst()方法===================null
==========测试iterable为空 - getFirst()方法==================2
==========测试iterable为空 - getFirst()方法==================null
5、获取末尾节点方法 - getLast()
Iterables
提供了获取指定Iterable
末尾节点的方法 - getLast(Iterable<? extends T> iterable, @Nullable T defaultValue)
,如果Iterable
不为empty
,返回末尾节点,否则返回默认节点;如果为NULL
抛出NPE
.
实验代码:
//测试getLast方法 - 如果为空抛出NoSuchElementException
System.out.println("==========测试iterable不为空 - getLast()方法===================" + Iterables.getLast(testIterable, 2));
System.out.println("==========测试iterable为空 - getLast()方法==================" + Iterables.getLast(testIterable1, 2));
System.out.println("==========测试iterable为null - getLast()方法==================" + Iterables.getLast(testIterable6, 2));
实验结果:
==========测试iterable不为空 - getLast()方法===================4
==========测试iterable为空 - getLast()方法==================2
Exception in thread "main" java.lang.NullPointerException
at com.google.common.collect.Iterables.getLast(Iterables.java:796)
at com.toxic.anepoch.guava.parsing.powerfuleUtils.Test.main(Test.java:65)
6、获取不可变的Iterable
方法 - unmodifiableIterable()
当我们想将对应的Iterable变为不可变的Iterable时,可以使用Iterables.unmodifiableIterable()
方法,它将返回指定iterable的不可变视图
实验代码:
//测试返回一个不可修改的视图
System.out.println("==========测试返回不可变视图unmodifiableIterable()方法==================" + Iterables.unmodifiableIterable(testIterable));
实验结果:
==========测试返回不可变视图unmodifiableIterable()方法==================[null, 1, 2, 2, 3, 4]
7、获取首位起,指定大小的Iterable方法 - limit()
当我们想类似limit操作的时候,Iterables
也提供了对应的limit()
方法
实验代码:
//测试返回一个limit的视图
System.out.println("==========测试返回不可变视图limit()方法==================" + Iterables.limit(testIterable, 3));
实验结果:
==========测试返回不可变视图limit()方法==================[null, 1, 2]
8、获取单个节点的Iterable节点方法 - getOnlyElement()
getOnlyElement()
方法返回指定Iterable
唯一元素,
如果iterable是空则返回指定的默认值;
如果只有一个元素,则返回当前元素,否则抛出非法参数异常
实验代码:
//测试返回唯一元素,方法实现为如果iterable是空则返回指定的默认值,如果只有一个元素,则返回当前元素,否则抛出非法参数异常
System.out.println("==========测试返回唯一元素getOnlyElement()方法==================" + Iterables.getOnlyElement(testIterable5, 3));
System.out.println("==========测试返回唯一元素getOnlyElement()方法==================" + Iterables.getOnlyElement(testIterable3, 3));
实验结果:
==========测试返回唯一元素getOnlyElement()方法==================2
Exception in thread "main" java.lang.IllegalArgumentException: expected one element but was: <2, 4, 3>
at com.google.common.collect.Iterators.getOnlyElement(Iterators.java:322)
at com.google.common.collect.Iterators.getOnlyElement(Iterators.java:335)
at com.google.common.collect.Iterables.getOnlyElement(Iterables.java:306)
at com.toxic.anepoch.guava.parsing.powerfuleUtils.Test.main(Test.java:79)
三、加强型流利的Iterable类 - FluentIterable
......未完待续