Java 8流是否类似于RxJava observables?
Java 8流定义:
新
java.util.stream包中的类提供Stream API以支持对元素流的功能样式操作.
我经常遇到Java lambda表达式的问题,当我想在对象的任意属性或方法上使用distinct()一个流时,但想要保留对象而不是将其映射到该属性或方法.我开始创建这里讨论的容器,但我开始做足够的事情,它变得烦人,并制作了很多样板类.
我将这个Pairing类放在一起,该类包含两个类型的两个对象,并允许您指定左,右或两个对象的键控.我的问题是......对于某些类型的关键供应商,distinct()是否真的没有内置的lambda流功能?那真让我感到惊讶.如果没有,该课程能否可靠地完成该功能?
以下是它的调用方式
BigDecimal totalShare = orders.stream().map(c -> Pairing.keyLeft(c.getCompany().getId(), c.getShare())).distinct().map(Pairing::getRightItem).reduce(BigDecimal.ZERO, (x,y) -> x.add(y));
Run Code Online (Sandbox Code Playgroud)
这是配对课程
public final class Pairing<X,Y> {
private final X item1;
private final Y item2;
private final KeySetup keySetup;
private static enum KeySetup {LEFT,RIGHT,BOTH};
private Pairing(X item1, Y item2, KeySetup keySetup) {
this.item1 = item1;
this.item2 = item2;
this.keySetup = keySetup;
}
public X getLeftItem() {
return item1;
}
public Y getRightItem() {
return item2;
}
public static <X,Y> Pairing<X,Y> keyLeft(X item1, Y item2) { …Run Code Online (Sandbox Code Playgroud) 我试图基于某些属性从对象列表中删除重复项.
我们可以使用java 8以简单的方式完成它
List<Employee> employee
Run Code Online (Sandbox Code Playgroud)
我们可以根据id员工的财产从中删除重复项.我已经看到帖子从字符串的arraylist中删除重复的字符串.
如何在Java 8 Stream上实现"分区"操作?通过分区,我的意思是,将流划分为给定大小的子流.不知何故,它将与Guava Iterators.partition()方法完全相同,只是希望分区是懒惰评估的Streams而不是List的.
在java 8中,检查List是否包含任何重复的最佳方法是什么?
我的想法是这样的:
list.size() != list.stream().distinct().count()
Run Code Online (Sandbox Code Playgroud)
这是最好的方式吗?
我有一个列表/对象集合,可能有也可能没有相同的属性值.获得具有相同属性的对象的明确列表的最简单方法是什么?一种集合类型最适合此目的吗?例如,在C#中,我可以使用LINQ执行以下操作.
var recipients = (from recipient in recipientList
select recipient).Distinct();
Run Code Online (Sandbox Code Playgroud)
我最初的想法是使用lambdaj(链接文本),但它似乎不支持这一点.
我正在阅读有关无国籍状态的文章并在文档中遇到过这个问题:
如果流操作的行为参数是有状态的,则流管道结果可能是不确定的或不正确的.有状态lambda(或实现适当功能接口的其他对象)的结果取决于在流管道执行期间可能发生变化的任何状态.
现在,如果我有一个字符串列表(strList比如说),然后尝试使用并行流从中删除重复的字符串,方法如下:
List<String> resultOne = strList.parallelStream().distinct().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
或者如果我们想要不区分大小写:
List<String> result2 = strList.parallelStream().map(String::toLowerCase)
.distinct().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
此代码是否有任何问题,因为并行流将分割输入并且在一个块中不同并不一定意味着在整个输入中是不同的?
这distinct是有状态操作,并且在有状态中间操作的情况下,并行流可能需要多次通过或大量缓冲开销.distinct如果元素的排序不相关,也可以更有效地实现.另外根据文件:
对于有序流,不同元素的选择是稳定的(对于重复元素,保留在遇到顺序中首先出现的元素.)对于无序流,不进行稳定性保证.
但是在有序流并行运行的情况下,不同可能是不稳定的 - 意味着它将在重复的情况下保留任意元素,而不一定是distinct其他情况下预期的第一个元素.
从链接:
在内部,distinct()操作保持一个包含先前已经看到的元素的Set,但它隐藏在操作中,我们无法从应用程序代码中获取它.
因此,在并行流的情况下,它可能会消耗整个流,或者可能使用CHM(类似于ConcurrentHashMap.newKeySet()).对于有序的,很可能是使用LinkedHashSet或类似的结构.
在我发布这个问题之前,我在这里发现了类似的问题.但答案是基于一个字符串.但是,我在这里有不同的情况.我不是要删除String而是另一个名为AwardYearSource的对象.该类有一个名为year的int属性.所以我想删除基于年份的重复项.即如果有不止一次提到的2010年,我想删除该AwardYearSource对象.我怎样才能做到这一点?
假设我们有两个流如下:
IntStream stream1 = Arrays.stream(new int[] {13, 1, 3, 5, 7, 9});
IntStream stream2 = Arrays.stream(new int[] {1, 2, 6, 14, 8, 10, 12});
stream1.merge(stream2); // some method which is used to merge two streams.
Run Code Online (Sandbox Code Playgroud)
是否有任何方便的方法使用Java 8流API将两个流合并到[13,1,2,3,5,6,7,8,9,10,12,14](顺序无关紧要) .或者我们只能同时处理一个流?
此外,如果两个流是对象流,如何只保留不同的对象,而不覆盖equals()和hashCode()方法?例如:
public class Student {
private String no;
private String name;
}
Student s1 = new Student("1", "May");
Student s2 = new Student("2", "Bob");
Student s3 = new Student("1", "Marry");
Stream<Student> stream1 = Stream.of(s1, s2);
Stream<Student> stream2 = …Run Code Online (Sandbox Code Playgroud) 说我有这个水果清单: -
List<String> f = Arrays.asList("Banana", "Apple", "Grape", "Orange", "Kiwi");
Run Code Online (Sandbox Code Playgroud)
我需要在每个水果前面加一个序列号并打印出来.水果或序列号的顺序无关紧要.所以这是一个有效的输出: -
4. Kiwi
3. Orange
1. Grape
2. Apple
5. Banana
Run Code Online (Sandbox Code Playgroud)
解决方案#1
AtomicInteger number = new AtomicInteger(0);
String result = f.parallelStream()
.map(i -> String.format("%d. %s", number.incrementAndGet(), i))
.collect(Collectors.joining("\n"));
Run Code Online (Sandbox Code Playgroud)
解决方案#2
String result = IntStream.rangeClosed(1, f.size())
.parallel()
.mapToObj(i -> String.format("%d. %s", i, f.get(i - 1)))
.collect(Collectors.joining("\n"));
Run Code Online (Sandbox Code Playgroud)
题
为什么解决方案#1是一种不好的做法?我在很多地方已经看到AtomicInteger基础解决方案很糟糕(比如在这个答案中),特别是在并行流处理中(这就是我使用上面的并行流来尝试遇到问题的原因).
我查看了这些问题/答案: -
在哪些情况下,Stream操作应该是有状态的?
使用AtomicInteger在Stream中进行索引是一种合法的方式吗?
Java 8:计算lambda迭代的首选方法?
他们只是提到(除非我错过了什么)"可能会出现意想不到的结果".像什么?它可以在这个例子中发生吗?如果没有,你能为我提供一个可能发生的例子吗?
至于" 不保证应用映射器函数的顺序 ",那么这就是并行处理的本质,所以我接受它,而且,在这个特定的例子中,顺序无关紧要.
AtomicInteger 是线程安全的,所以它不应该是并行处理的问题.
有人可以提供使用这种基于状态的解决方案时会出现问题的示例吗?
java ×9
java-8 ×8
java-stream ×6
list ×3
arraylist ×1
collections ×1
duplicates ×1
lambda ×1
observable ×1
rx-java ×1
set ×1