list.stream.filter去重
时间: 2023-04-25 21:02:05 浏览: 179
list.stream.filter去重是Java 8中Stream API提供的一种操作,可以对一个List进行去重操作。具体实现方式是通过Stream API中的distinct()方法,该方法会返回一个去重后的Stream。使用filter()方法可以对Stream中的元素进行过滤,只保留符合条件的元素。因此,list.stream.filter去重的实现方式是先将List转换为Stream,然后使用distinct()方法进行去重,最后使用filter()方法对去重后的Stream进行过滤。
相关问题
list.stream.filter 根据某个字段去重
您好!要根据List中的某个字段进行去重和筛选,可以使用Java 8中的Stream API中的filter和distinct方法。
假设我们有一个List<User>,每个User对象包含id和name属性,现在要根据id属性进行去重和筛选,可以使用以下代码:
```
List<User> userList = ...; // 假设我们已经有了一个List<User>对象
List<User> distinctList = userList.stream()
.filter(distinctByKey(User::getId))
.collect(Collectors.toList());
```
上面的代码中,我们使用了Stream的filter()方法和自定义的distinctByKey()方法。distinctByKey()方法的实现如下:
```
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
```
这个方法会根据传入的keyExtractor函数提取User对象的id属性,并使用ConcurrentHashMap来记录已经出现过的id值。如果当前id值是第一次出现,那么就返回true,否则返回false。这个方法会作为filter()方法的参数,用于筛选不重复的User对象。
需要注意的是,这种方法使用了ConcurrentHashMap来记录已经出现过的id值,因此可以在多线程环境下使用。如果您的应用程序是单线程的,可以使用普通的HashMap来代替ConcurrentHashMap。
list.stream 分组去重
### 使用 Java Stream API 对 List 进行分组和去重
对于给定的 `List`,如果目标是对对象基于特定字段进行分组以及去重,则可以通过组合使用 `Collectors.groupingBy()` 和 `Collectors.collectingAndThen()` 或者利用自定义比较逻辑配合 `distinct()` 来完成此目的。
#### 基于单个属性去重并收集到新列表
假设存在一个类 `Person`,其具有 `name` 属性和其他可能不同的属性。为了仅保留名字唯一的人:
```java
import java.util.*;
import java.util.stream.Collectors;
class Person {
private String name;
// other fields...
public Person(String name) { this.name = name; }
public String getName() { return name; }
@Override
public boolean equals(Object o){
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return Objects.equals(name, person.name);
}
@Override
public int hashCode(){
return Objects.hash(name);
}
}
public class Main{
public static void main(String[] args){
List<Person> people = Arrays.asList(
new Person("Alice"),
new Person("Bob"),
new Person("Alice") // duplicate entry
);
List<Person> uniquePeople = people.stream()
.distinct() // removes duplicates based on the natural key defined by equals/hashCode
.collect(Collectors.toList());
System.out.println(uniquePeople.size()); // prints "2"
}
}
```
这段代码展示了如何通过覆盖 `equals` 和 `hashCode` 方法来确保根据名称判断两个 `Person` 实例是否相同[^1]。
#### 按照某个条件分组后再去重
当需要按照某些标准先对元素进行分类再从中挑选代表时,可以采用如下方式:
```java
Map<String, Optional<Person>> groupedByName =
people.stream()
.collect(Collectors.groupingBy(Person::getName,
Collectors.reducing((p1, p2) -> p1))); // keeps first occurrence of each group
// Extract values from map and flatten into a list
List<Person> representatives = groupedByName.values().stream()
.map(Optional::get)
.collect(Collectors.toList());
```
这里采用了 `groupingBy` 结合 `reducing` 的策略,在每组内部只留下第一个遇到的对象作为该组的代表[^3]。
#### 多字段联合判定重复项
如果有更复杂的业务场景,比如要依据多个字段共同决定两条记录是不是应该视为同一个实体的话,可以在流中间操作阶段加入过滤器或者创建复合键来进行区分:
```java
Set<CompositeKey> seenKeys = new HashSet<>();
people.stream()
.filter(p -> seenKeys.add(new CompositeKey(p.getName(), /*other properties*/)))
.collect(Collectors.toList());
```
其中 `CompositeKey` 是一个实现了 `equals` 和 `hashCode` 接口的新类,用来表示由若干成员变量组成的唯一标识符。
阅读全文
相关推荐
















