java-如何从两个流中获取相似的元素并收集由此形成的对而不丢失顺序?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-如何从两个流中获取相似的元素并收集由此形成的对而不丢失顺序?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2656字,纯文字阅读大概需要4分钟。
内容图文
![java-如何从两个流中获取相似的元素并收集由此形成的对而不丢失顺序?](/upload/InfoBanner/zyjiaocheng/683/7b421ad121be4bff8a375da31d9296b4.jpg)
例如:
输入是无限流,可作为地图每次减少的有限列表使用:
list 1: List<String> : {"a1_5", "c1_91", "b1_43", "b1_76", "a1_68"}
list 2: List<String> : {"c2_3", "b2_19", "c2_29", "a2_45", "b2_53"}
我的输出应该是由List输出实例组成的无限流:
List<String> : {"a1_5,a2_45", "c1_91,c2_3", "b1_43,b2_19", "b1_76,b2_53", "a1_68,a2_45"}
或者输出可能是:
List<String> : {"c1_91,c2_3", "b1_43,b2_19", "a1_5,a2_45", "b1_76,b2_53"}
解决方法:
如果问题是关于Java 8 Streams的,则可以使用非常复杂的自定义Spliterator来解决,如下所示:
public static <T,K,R> Stream<R> pairs(Stream<T> a, Stream<T> b,
Function<T, K> keyExtractor, BiFunction<T, T, R> merger) {
Map<K, Queue<T>> aMap = new HashMap<>();
Map<K, Queue<T>> bMap = new HashMap<>();
Spliterator<T> aSpltr = a.spliterator();
Spliterator<T> bSpltr = b.spliterator();
Spliterator<R> res = new Spliterators.AbstractSpliterator<R>(Math.min(
aSpltr.estimateSize(), bSpltr.estimateSize()), Spliterator.ORDERED) {
T at, bt;
boolean hasBuffered = false;
R buf;
@Override
public boolean tryAdvance(Consumer<? super R> action) {
if(hasBuffered) {
hasBuffered = false;
action.accept(buf);
return true;
}
while(true) {
if(!aSpltr.tryAdvance(t -> at = t) || !bSpltr.tryAdvance(t -> bt = t))
return false;
K ak = keyExtractor.apply(at);
K bk = keyExtractor.apply(bt);
Queue<T> bq = bMap.get(ak);
boolean found = false;
if(bq != null) {
found = true;
action.accept(merger.apply(at, bq.poll()));
if(bq.isEmpty()) bMap.remove(ak);
} else {
aMap.computeIfAbsent(ak, k -> new ArrayDeque<>()).add(at);
}
Queue<T> aq = aMap.get(bk);
if(aq != null) {
if(found) {
hasBuffered = true;
buf = merger.apply(aq.poll(), bt);
} else {
found = true;
action.accept(merger.apply(aq.poll(), bt));
}
if(aq.isEmpty()) aMap.remove(bk);
} else {
bMap.computeIfAbsent(bk, k -> new ArrayDeque<>()).add(bt);
}
if(found)
return true;
}
}
};
return StreamSupport.stream(res, a.isParallel() || b.isParallel())
.onClose(a::close).onClose(b::close);
}
此方法接受两个流(可能是无限个),键提取器功能(在您的情况下,需要提取第一个字符)和合并功能(如何将两个元素组合在一起;在您的情况下,使用“,”联接).这是用法示例:
List<String> list1 = Arrays.asList("a1_5", "c1_91", "b1_43", "b1_76", "a1_68");
List<String> list2 = Arrays.asList("c2_3", "b2_19", "c2_29", "a2_45", "b2_53");
pairs(list1.stream(), list2.stream(), s -> s.charAt(0), (a, b) -> a+","+b)
.forEach(System.out::println);
输出:
c1_91,c2_3
b1_43,b2_19
a1_5,a2_45
b1_76,b2_53
实际无限流的替代示例:将来自两个流的随机数对组合在一起,它们的不同之处仅在于最后一位:
pairs(new Random().ints(0, 1000).boxed(), new Random().ints(0, 1000).boxed(),
i -> i/10, (a, b) -> a+","+b)
.limit(100)
.forEach(System.out::println);
请注意,对于无限流,如果流中有许多未配对的元素,则可能会出现OutOfMemoryError.
内容总结
以上是互联网集市为您收集整理的java-如何从两个流中获取相似的元素并收集由此形成的对而不丢失顺序?全部内容,希望文章能够帮你解决java-如何从两个流中获取相似的元素并收集由此形成的对而不丢失顺序?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。