stream java如何取出集合里面的两个字段并封装为另一个集合
时间: 2024-05-12 21:14:54 浏览: 130
可以使用Java 8的Stream API来完成这个任务。假设你有一个包含对象的集合,每个对象都有两个字段`field1`和`field2`。你想要从这个集合中取出这两个字段,并将它们封装为另一个对象的集合。以下是一种可能的实现方法:
```java
List<OriginalObject> originalList = ...; // 原始集合
List<NewObject> newList = originalList.stream()
.map(o -> new NewObject(o.getField1(), o.getField2())) // 将原始对象转换为新对象
.collect(Collectors.toList()); // 封装为新的集合
```
这个代码片段使用了`map()`方法将原始对象转换为新对象,然后使用`collect()`方法将转换后的对象收集到一个新的集合中。`NewObject`是一个包含`field1`和`field2`字段的对象,你需要根据自己的需求来定义它。
相关问题
Java8写一个共通方法,将两个类型不同且数据量不一致的stream输入按多个字段进行匹配,并返回匹配成功的两个stream输出数据。已知stream输入已按匹配字段排好序,使用了迭代器和循环来避免嵌套循环。
可以使用Java 8中的Stream API来实现这个共通方法,具体实现如下:
```java
public static <T, R> List<Pair<T, R>> matchStreamsByFields(
Stream<T> stream1, Stream<R> stream2, Function<T, ?>[] matchingFields1, Function<R, ?>[] matchingFields2) {
List<Pair<T, R>> matchedPairs = new ArrayList<>();
Iterator<T> iterator1 = stream1.iterator();
Iterator<R> iterator2 = stream2.iterator();
while (iterator1.hasNext() && iterator2.hasNext()) {
T obj1 = iterator1.next();
R obj2 = iterator2.next();
boolean matched = true;
for (int i = 0; i < matchingFields1.length && matched; i++) {
Object field1 = matchingFields1[i].apply(obj1);
Object field2 = matchingFields2[i].apply(obj2);
matched = Objects.equals(field1, field2);
}
if (matched) {
matchedPairs.add(new Pair<>(obj1, obj2));
} else {
// 如果不匹配则将迭代器向前推进一步
if (compareFields(matchingFields1, obj1, matchingFields2, obj2) < 0) {
iterator2.previous();
} else {
iterator1.previous();
}
}
}
return matchedPairs;
}
// 比较两个对象的指定字段,用于推进迭代器
private static <T, R> int compareFields(Function<T, ?>[] fields1, T obj1, Function<R, ?>[] fields2, R obj2) {
for (int i = 0; i < fields1.length; i++) {
Object field1 = fields1[i].apply(obj1);
Object field2 = fields2[i].apply(obj2);
int cmp = Objects.compare(field1, field2, Comparator.nullsFirst(Comparator.naturalOrder()));
if (cmp != 0) {
return cmp;
}
}
return 0;
}
```
这个方法接受两个不同类型的Stream对象,以及两个数组,每个数组包含了要进行匹配的字段所对应的Function对象。两个Stream对象分别按照匹配字段进行排序,然后使用迭代器和循环来遍历两个Stream,按照匹配字段一一比较,如果全部匹配成功,则将这两个对象封装成一个Pair对象,并添加到结果列表中。如果不匹配,则需要将迭代器向前推进一步,以便继续匹配下一个对象。
注意,在比较两个对象的指定字段时,需要使用`Objects.compare`方法,并使用`Comparator.nullsFirst(Comparator.naturalOrder())`来处理空值的情况。另外,这个方法的返回值是一个包含了匹配成功的Pair对象的列表。你可以根据需要将其转换为其他类型的集合对象。
java 两个List 根据多个字段去重
可以使用 Java 8 的 Stream API 来实现多字段去重。假设有两个 `List` 对象 `list1` 和 `list2`,每个列表都包含一个 `Person` 类型的对象,该对象有两个字段 `name` 和 `age`,可以按照以下方式去重:
```java
List<Person> distinctList = Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(
p -> Arrays.asList(p.getName(), p.getAge())))),
ArrayList::new));
```
上述代码中,使用 `Stream.concat` 方法将两个列表合并为一个流,并使用 `distinct` 方法去重。然后,使用 `Collectors.toCollection` 方法创建一个 `TreeSet` 集合,该集合可以根据多个字段去重。具体来说,`Comparator.comparing` 方法接收一个 `Function` 对象,该对象将每个 `Person` 对象映射为一个包含两个字段的列表,然后使用 `Arrays.asList` 方法将这个列表封装为 `List` 对象。这样,`TreeSet` 集合就可以根据这个列表进行去重。
最后,使用 `Collectors.collectingAndThen` 方法将 `TreeSet` 转换为 `ArrayList`,得到最终的去重后的列表。
阅读全文