java – 最简单的方式来索引一个集合的属性,该属性本身就是一个集合

前端之家收集整理的这篇文章主要介绍了java – 最简单的方式来索引一个集合的属性,该属性本身就是一个集合前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个列表< Foo>并想要一个番石榴Multimap< String,Foo>我们把它们的Collection< String>的每个标签分成了Foo getTags()函数.

我使用java 8,所以lambdas和方法引用是罚款/鼓励.

例如,如果我有:

  1. foo1,tags=a,b,c
  2. foo2,tags=c,d
  3. foo3,c,e

我会得到一个Multimap< String,Foo>有:

  1. a -> foo1,foo3
  2. b -> foo1
  3. c -> foo1,foo2,foo3
  4. d -> foo2
  5. e -> foo3

解决方法

您可以使用自定义收藏夹:
  1. Multimap<String,Foo> map = list.stream().collect(
  2. ImmutableMultimap::builder,(builder,value) -> value.getTags().forEach(tag -> builder.put(tag,value)),(builder1,builder2) -> builder1.putAll(builder2.build())
  3. ).build();

这不会引起额外的副作用(参见here),是并发的,比较惯用的.

您还可以将这些特别的羔羊提取成一个完整的收藏家,如下所示:

  1. public static <T,K> Collector<T,?,Multimap<K,T>> toMultimapByKey(Function<? super T,? extends Iterable<? extends K>> keysMapper) {
  2. return new MultimapCollector<>(keysMapper);
  3. }
  4.  
  5. private static class MultimapCollector<T,K> implements Collector<T,ImmutableMultimap.Builder<K,T>,T>> {
  6. private final Function<? super T,? extends Iterable<? extends K>> keysMapper;
  7.  
  8. private MultimapCollector(Function<? super T,? extends Iterable<? extends K>> keysMapper) {
  9. this.keysMapper = keysMapper;
  10. }
  11.  
  12. @Override
  13. public Supplier<ImmutableMultimap.Builder<K,T>> supplier() {
  14. return ImmutableMultimap::builder;
  15. }
  16.  
  17. @Override
  18. public BiConsumer<ImmutableMultimap.Builder<K,T> accumulator() {
  19. return (builder,value) -> keysMapper.apply(value).forEach(k -> builder.put(k,value));
  20. }
  21.  
  22. @Override
  23. public BinaryOperator<ImmutableMultimap.Builder<K,T>> combiner() {
  24. return (b1,b2) -> b1.putAll(b2.build());
  25. }
  26.  
  27. @Override
  28. public Function<ImmutableMultimap.Builder<K,T>> finisher() {
  29. return ImmutableMultimap.Builder<K,T>::build;
  30. }
  31.  
  32. @Override
  33. public Set<Characteristics> characteristics() {
  34. return Collections.emptySet();
  35. }
  36. }

那么收藏将如下所示:

  1. Multimap<String,Foo> map = list.stream().collect(toMultimapByKey(Foo::getTags));

如果您的订单不重要,您还可以从特性()方法返回EnumSet.of(Characteristics.UNORDERED).这可以使内部收集机械更有效地起作用,特别是在并行还原的情况下.

猜你在找的Java相关文章