Maison >Java >javaDidacticiel >Comment utiliser Stream de Java 8 pour implémenter la déduplication de liste ?

Comment utiliser Stream de Java 8 pour implémenter la déduplication de liste ?

WBOY
WBOYavant
2023-05-08 11:07:142181parcourir

1. La méthode distinct() de Stream

distinct() est une méthode fournie par Stream en Java 8. Elle renvoie un flux composé de différents éléments dans le flux. distinct() utilise les méthodes hashCode() et eqauls() pour obtenir des éléments distincts.

Par conséquent, la classe qui doit être dédupliquée doit implémenter les méthodes hashCode() et equals(). En d’autres termes, nous pouvons répondre à certains besoins particuliers en remplaçant les méthodes personnalisées hashCode() et equals(). La méthode

distinct() est déclarée comme suit :

Stream<T> distinct();

1.1 Pour la déduplication de la liste de chaînes

Parce que la classe String a remplacé les méthodes equals() et hashCode(), la déduplication peut réussir.

@Test
public void listDistinctByStreamDistinct() {
  // 1. 对于 String 列表去重
  List<String> stringList = new ArrayList<String>() {{
    add("A");
    add("A");
    add("B");
    add("B");
    add("C");
  }};
  out.print("去重前:");
  for (String s : stringList) {
    out.print(s);
  }
  out.println();
  stringList = stringList.stream().distinct().collect(Collectors.toList());
  out.print("去重后:");
  for (String s : stringList) {
    out.print(s);
  }
  out.println();

}

Les résultats sont les suivants :

Avant la déduplication : AABBC
Après la déduplication : ABC

1.2 Pour la déduplication de la liste des classes d'entités

Remarque : Dans le code, nous utilisons l'annotation @Data du plug-in Lombok- dans, qui peut être automatiquement écrasé. Écrivez les méthodes equals() et hashCode().

/**
* 定义一个实体类
*/  
@Data
public class Student {
  private String stuNo;
  private String name;
}
@Test
public void listDistinctByStreamDistinct() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    // 1. 对于 Student 列表去重
    List<Student> studentList = getStudentList();
    out.print("去重前:");
    out.println(objectMapper.writeValueAsString(studentList));
    studentList = studentList.stream().distinct().collect(Collectors.toList());
    out.print("去重后:");
    out.println(objectMapper.writeValueAsString(studentList));
  }

Les résultats sont les suivants :

Avant la déduplication : [{"stuNo": "001", "name": "Tom"}, {"stuNo": "002", "name": "Mike" }, {"stuNo": "001", "name": "Tom"}]
Après la déduplication : [{"stuNo": "001", "name": "Tom"}, {"stuNo": "002 " ,"name":"Mike"}]

2. Déduplication selon un certain attribut de l'Objet dans la Listea87fdacec66f0909fc0757c19f2d2b1d

2.1 Créer une nouvelle liste

@Test
  public void distinctByProperty1() throws JsonProcessingException {
    // 这里第一种方法我们通过新创建一个只有不同元素列表来实现根据对象某个属性去重
    ObjectMapper objectMapper = new ObjectMapper();
    List<Student> studentList = getStudentList();
    out.print("去重前        :");
    out.println(objectMapper.writeValueAsString(studentList));
    studentList = studentList.stream().distinct().collect(Collectors.toList());
    out.print("distinct去重后:");
    out.println(objectMapper.writeValueAsString(studentList));
    // 这里我们引入了两个静态方法,以及通过 TreeSet<> 来达到获取不同元素的效果
    // 1. import static java.util.stream.Collectors.collectingAndThen;
    // 2. import static java.util.stream.Collectors.toCollection;
    studentList = studentList.stream().collect(
      collectingAndThen(
        toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new)
    );
    out.print("根据名字去重后 :");
    out.println(objectMapper.writeValueAsString(studentList));
  }

Le résultat est le suivant :

Avant la déduplication :[{" stuNo": "001", "name": "Tom"},{"stuNo": "001", "name": "Tom"}, {"stuNo": "003", "name" :"Tom" }]
Après une déduplication distincte : [{"stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
Déduplication basé sur le nom Après : [{"stuNo":"001","name":"Tom"}]

2.2 Grâce à la méthode filter()

Nous créons d'abord une méthode en tant que paramètre de Stream.filter() , dont le type de retour est Predicate, le principe est de déterminer si un élément peut être ajouté au Set. Le code est le suivant :

private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

Utiliser comme suit :

@Test
  public void distinctByProperty2() throws JsonProcessingException {
    // 这里第二种方法我们通过过滤来实现根据对象某个属性去重
    ObjectMapper objectMapper = new ObjectMapper();
    List<Student> studentList = getStudentList();
    out.print("去重前        :");
    out.println(objectMapper.writeValueAsString(studentList));
    studentList = studentList.stream().distinct().collect(Collectors.toList());
    out.print("distinct去重后:");
    out.println(objectMapper.writeValueAsString(studentList));
    // 这里我们将 distinctByKey() 方法作为 filter() 的参数,过滤掉那些不能加入到 set 的元素
    studentList = studentList.stream().filter(distinctByKey(Student::getName)).collect(Collectors.toList());
    out.print("根据名字去重后 :");
    out.println(objectMapper.writeValueAsString(studentList));
  }

Le résultat est le suivant :

Avant la déduplication : [{"stuNo":"001","name" :"Tom"},{"stuNo":"001","name":"Tom"},{"stuNo":"003","name": "Tom"}]
distinct après avoir supprimé les doublons :[{ "stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]
Après suppression des doublons en fonction du nom : [{"stuNo":"001 ","name":"Tom"}]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer