Java 绘制河流地图<;T>;到地图<;T、 长期>;那算吗?
我有一个Java 绘制河流地图<;T>;到地图<;T、 长期>;那算吗?,java,mapping,java-8,java-stream,Java,Mapping,Java 8,Java Stream,我有一个流,是否可以生成一个映射,将每个元素的计数增加一个?我还想知道它是否可以将T,Long反转为Long,T,然后将其存储在映射中,示例输入/输出: 流的内容示例: 第一个问题需要输出: (kgj, 1) (def, 2) (dgh, 3) 最终想要的输出: (1, kgj) (2, def) (3, dgh) 到目前为止,对于流,我所拥有的: 这将当前将流转换为具有不同元素的流,然后转换为统计发生次数的映射,这不是我想要的,因为我希望它在经过的每个元素上继续计数 有什么方法可以满足我的
流
,是否可以生成一个映射
,将每个元素的计数增加一个?我还想知道它是否可以将T,Long
反转为Long,T
,然后将其存储在映射中,示例输入/输出:
流的内容示例
:
第一个问题需要输出:
(kgj, 1)
(def, 2)
(dgh, 3)
最终想要的输出:
(1, kgj)
(2, def)
(3, dgh)
到目前为止,对于流
,我所拥有的:
这将当前将流
转换为具有不同元素的流
,然后转换为统计发生次数的映射
,这不是我想要的,因为我希望它在经过的每个元素上继续计数
有什么方法可以满足我的要求吗?您可以编写自己的收集器,为您计算遇到的元素。类似于以下工作:
Stream<String> strings = Stream.of("kgj", "def", "dgh");
strings.distinct().collect(Collector.of(
HashMap::new,
(BiConsumer<Map<String, Long>, String>) (map, str) -> {
map.put(str, Long.valueOf(map.size() + 1));
},
(left, right) -> {
long s = left.size();
right.entrySet().forEach(e -> left.put(e.getKey(),
Long.valueOf(
e.getValue()
.longValue()
+ s)));
return left;
})).forEach((k, v) -> System.out.println("k = " + k + " / v = " + v));
Stream strings=Stream.of(“kgj”、“def”、“dgh”);
strings.distinct().collect(Collector.of(
HashMap::新建,
(双消费者)(地图、街道)->{
map.put(str,Long.valueOf(map.size()+1));
},
(左,右)->{
长s=左。大小();
right.entrySet().forEach(e->left.put(e.getKey(),
长期价值(
e、 getValue()
.longValue()
+(s);;
左转;
})).forEach((k,v)->System.out.println(“k=“+k+”/v=“+v”);
请注意,(有点复杂)组合器(在并行处理流的情况下需要使用Collector.of()
的第三个参数)。受@jpvee的启发,我制作了一个收集器
,它回答了问题的最后一个子问题,并打算更清楚一些:
public static <T> Collector<T, ?, Map<Long, T>> indexing() {
return Collector.of(
HashMap::new,
(map, t) -> map.put(Long.valueOf(map.size() + 1), t),
(left, right) -> {
final long size = left.size();
right.forEach((k, v) -> left.put(k + size, v));
return left;
},
Collector.Characteristics.CONCURRENT
);
}
公共静态收集器索引(){
返回收集器(
HashMap::新建,
(map,t)->map.put(Long.valueOf(map.size()+1),t),
(左,右)->{
最终长尺寸=left.size();
右.forEach((k,v)->左.put(k+大小,v));
左转;
},
Collector.Characteristics.CONCURRENT
);
}
它的作用是:
- 在
流
上操作时,它返回一个映射
,该映射用流的遭遇顺序索引T
- 它使用的是
收集器,它通常接受以下内容:
地图的供应商
- 向
映射添加一个元素的累加器
- 组合两个可能来自并发访问的映射的组合器
- 一系列特征
因此,我提供的是:
Supplier
:一个新的HashMap
BiConsumer
:获取映射并添加新元素的函数
BinaryOperator
:组合两个映射的函数
收集器.characteristics
:此方法的字符,允许并发执行李>
@assylias我想说,它提供了一个解决方法,感谢您指导我回答这个问题,但是它不是一个确定的答案,因此我认为您为什么将它作为一个评论发布。当使用重复输入(例如[“abc”、“def”、“abc”])时,您希望第一个问题的输出是什么?@jpvee它应该只计算不同的元素,(到目前为止,我已经有了这一点),对于streams,很容易通过list.stream().distinct()
获得一个稳定的distinct。在scala中,我只需要x.zipWithIndex
和第二个:x.zipWithIndex.map(x=>(x.\u 2,x.\u 1))
这会对性能造成什么影响?有没有办法“禁用”并行处理,因为你永远无法并行计算……或者你可以?收集器的一种有趣用法,但最终是O(n log n)及时。原因是每次合并只复制一半的元素,并且合并树中有logn级别。这可以并行运行,但足够大的n将淹没任何并行加速。
Stream<String> strings = Stream.of("kgj", "def", "dgh");
strings.distinct().collect(Collector.of(
HashMap::new,
(BiConsumer<Map<String, Long>, String>) (map, str) -> {
map.put(str, Long.valueOf(map.size() + 1));
},
(left, right) -> {
long s = left.size();
right.entrySet().forEach(e -> left.put(e.getKey(),
Long.valueOf(
e.getValue()
.longValue()
+ s)));
return left;
})).forEach((k, v) -> System.out.println("k = " + k + " / v = " + v));
public static <T> Collector<T, ?, Map<Long, T>> indexing() {
return Collector.of(
HashMap::new,
(map, t) -> map.put(Long.valueOf(map.size() + 1), t),
(left, right) -> {
final long size = left.size();
right.forEach((k, v) -> left.put(k + size, v));
return left;
},
Collector.Characteristics.CONCURRENT
);
}