我有以下几点:
Map<String, Map<String, List<SomeClass>>> someMap =
.... (streams and filtering, etc.)
.collect(Collectors.groupingBy(
x -> getSomeComputedAttribute(x),
Collectors.groupingBy(x -> getSomeOtherComputedAttribute(x));
到目前为止,这工作正常 - 我得到了正确的值,但问题是我需要将List转换为ImmutableList。有什么简单的方法可以做到这一点?
答案 0 :(得分:3)
至于pointed out by Louis Wasserman,最简单的解决方案是使用内置收集器收集到List
,并在后处理步骤中将收集的元素传输到ImmutableList
:< / p>
Map<String, Map<String, List<SomeClass>>> someMap =
/* your stream operation */
.collect(groupingBy(x -> getSomeComputedAttribute(x),
groupingBy(x -> getSomeOtherComputedAttribute(x),
collectingAndThen(toList(), ImmutableList::copyOf))));
这当然会有复制整个列表内容的轻微性能缺陷。
天然解决方案将是基于构建器的收集器,例如
public static <T> Collector<T,?,List<T>> toImmutableList() {
return Collector.of(
ImmutableList::<T>builder,
ImmutableList.Builder::add,
(b1,b2) -> b1.addAll(b2.build()),
ImmutableList.Builder::build);
}
并像
一样使用它Map<String, Map<String, List<SomeClass>>> someMap =
/* your stream operation */
.collect(groupingBy(x -> getSomeComputedAttribute(x),
groupingBy(x -> getSomeOtherComputedAttribute(x), toImmutableList())));
但令人惊讶的是,这不会获得任何性能提升,因为在几乎所有情况下构建ImmutableList
时仍会复制构建器的内容,因为它只会共享其内部数组(如果收集的数量)元素与数组的容量完全匹配。
不过,未来它可能会获得更新的Guava库的优势......
或者,您可以重新考虑它是否真的必须是不可变列表的Guava实现。您可以通过以下方式获得不可复制的列表而无需复制步骤:
Map<String, Map<String, List<SomeClass>>> someMap =
/* your stream operation */
.collect(groupingBy(x -> getSomeComputedAttribute(x),
groupingBy(x -> getSomeOtherComputedAttribute(x),
collectingAndThen(toList(), Collections::unmodifiableList))));
答案 1 :(得分:2)
如果你被限制在一个Java 8之前的番石榴 - 一个即将推出 - 那么可能最简单的解决方法(而不是一个坏的,老实说)collectingAndThen(toList(), ImmutableList::copyOf)
。