我有一个形状流
Stream<Shape> shapes = Arrays.asList(TRIANGLE, CIRCLE, SQUARE, SQUARE, CIRCLE, TRIANGLE, TRIANGLE).stream();
其中Shape
是
public enum Shape {TRIANGLE, CIRCLE, SQUARE}
如何编写将形状流分组为a的函数
Map<Shape, List<Integer>>
这样根据形状收集指数?
public Map<Shape, List<Integer>> indexedPartition(Stream<Shape> shapes) {
//code here
}
在当前示例中,函数indexedPartition
的输出看起来像
TRIANGE -> {0, 5, 6}
CIRCLE -> {1, 4}
SQUARE -> {2, 3}
在Scala中我会做类似
的事情val indices = Stream.from(0)
object Shape extends Enumeration {
type Shape = Value
val CIRCLE, TRIANGLE, SQUARE = Value
}
val shapes = Stream(Shape.TRIANGLE, Shape.CIRCLE, Shape.SQUARE, Shape.SQUARE, Shape.CIRCLE, Shape.TRIANGLE, Shape.TRIANGLE)
(shapes zip indices).groupBy{ case (s, i) => s }.mapValues(l => l.map(_._2))
//res0: scala.collection.immutable.Map[Shape.Value,List[Int]] = Map(SQUARE -> List(2, 3), TRIANGLE -> List(0, 5, 6), CIRCLE -> List(1, 4))
我尝试在java中使用Collectors.groupingBy,但我无法绕过它。
答案 0 :(得分:3)
流式传输索引:
import static java.util.stream.Collectors.groupingBy;
List<Shape> shapes = Arrays.asList(TRIANGLE, CIRCLE, SQUARE, SQUARE, CIRCLE, TRIANGLE, TRIANGLE);
result = IntStream.range(0, shapes.size())
.boxed()
.collect(groupingBy(shapes::get));
答案 1 :(得分:1)
可以实现Collector
,它记录在流处理结束时遇到的元素的索引。当然,对于无序流,这个数字是没有意义的,如果你改变了filter
或flatMap
等中间操作的大小,那么这个数字将不再反映原始数组中的位置。
class IndexCollector<K> {
int total;
Map<K,List<Integer>> map = new HashMap<>();
public static <T> Collector<T,?,Map<T,List<Integer>>> get() {
return Collector.of(IndexCollector<T>::new,
(c,t) -> c.map.computeIfAbsent(t, x -> new ArrayList<>()).add(c.total++),
(c1,c2) -> merge(c1, c2),
c -> c.map);
}
static <T> IndexCollector<T> merge(IndexCollector<T> a, IndexCollector<T> b) {
if(a.total == 0) return b;
if(b.total != 0) {
int offset = a.total;
b.map.forEach((t,l) -> {
List<Integer> target = a.map.computeIfAbsent(t, x -> new ArrayList<>());
for(Integer i: l) target.add(i+offset);
});
a.total += b.total;
}
return a;
}
}
可以像
一样使用Map<Shape, List<Integer>> map =
Stream.of(TRIANGLE, CIRCLE, SQUARE, SQUARE, CIRCLE, TRIANGLE, TRIANGLE)
.collect(IndexCollector.get());
map.forEach((shape,list) -> System.out.printf("%-9s%s%n", shape, list));