我找不到使用Java流将一种类型(例如MyData
)的集合减少到另一种类型的对象(例如MyResult
)的解决方案。
@Test
public void streams() {
List<MyData> collection = Arrays.asList(
new MyData("1", "cool"),
new MyData("2", "green"),
new MyData("3", "night"));
// How reduce the collection with streams?
MyResult result = new MyResult();
collection.stream().forEach((e) -> {
if (e.key.equals("2")) {
result.color = e.value;
}
});
MyResult expectedResult = new MyResult();
expectedResult.color = "green";
assertThat(result).isEqualTo(expectedResult);
}
public static class MyData {
public String key;
public String value;
public MyData(String key, String value) {
this.key = key;
this.value = value;
}
}
public static class MyResult {
public String color;
public String material;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MyResult myResult = (MyResult) o;
return Objects.equals(this.color, myResult.color) &&
Objects.equals(this.material, myResult.material);
}
@Override
public int hashCode() {
return Objects.hash(this.color, this.material);
}
}
是否有使用某种减少或折叠的解决方案?
答案 0 :(得分:10)
你的意思是:
collection.stream()
.filter(e -> e.key.equals("2"))
.findFirst()
.orElse(null);//Or any default value
你甚至可以抛出异常:
collection.stream()
.filter(e -> e.key.equals("2"))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No data found"));
答案 1 :(得分:1)
您是否尝试根据条件将某种类型的列表转换为另一种类型?
MyResult result = new MyResult();
List<MyResult> resultList = collection.stream().filter(e -> e.key.equals("2")).map(e -> {
MyResult resultTemp = new MyResult();
result.color = e.value;
return result;
}).collect(Collectors.toList());
试试这个
答案 2 :(得分:0)
您可以先找到您正在寻找的元素
Optional<MyData> found = stream.filter(data -> data.key == 2).findFirst();
然后将其映射到您的结果
Optional<MyResult> result = found.map(data -> {
MyResult r = new MyResult();
r.color = data.color;
return r;
});
如果原始流不包含带有键2的项目,则匹配Optional
,现在您的MyResult
为空。
答案 3 :(得分:0)
您正在寻找的操作是Map。请阅读Stream文档以获取更多详细信息:https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
这是一个代码片段,用于将MyData对象列表映射到MyResult对象列表。
List<MyResult> collect = collection.stream().map(myData -> {
MyResult myResult = new MyResult();
myResult.color = myData.value;
return myResult;
}).collect(Collectors.toList());
如果您只想找到一个值,只需在Map转换之前添加滤镜转换。
List<MyResult> collect = collection.stream()
.filter(myData -> "2".equals(myData.key))
.map(myData -> {
MyResult myResult = new MyResult();
myResult.color = myData.value;
return myResult;
}).collect(Collectors.toList());
答案 4 :(得分:0)
我找到了使用Collector.of()
的解决方案。
Collector<MyData, MyResult, MyResult> myCollector = Collector.of(
() -> new MyResult(),
(a, e) -> {
if (e.key.equals("2")) {
a.color = e.value;
}
},
(a1, a2) -> null, // Not used, therefore not working scaffold
a -> a
);
MyResult result = collection.stream().collect(myCollector);
毕竟它不是习惯性的。