ホームページ  >  記事  >  Java  >  Java 8 の Stream を使用してリストの重複排除を実装するにはどうすればよいですか?

Java 8 の Stream を使用してリストの重複排除を実装するにはどうすればよいですか?

WBOY
WBOY転載
2023-05-08 11:07:142063ブラウズ

1. Stream

distinct() の distinct() メソッドは、Java 8 の Stream によって提供されるメソッドです。ストリーム内のさまざまな要素で構成されるストリームを返します。 unique() は hashCode() メソッドと eqauls() メソッドを使用して個別の要素を取得します。

したがって、重複排除が必要なクラスは hashCode() メソッドとquals() メソッドを実装する必要があります。言い換えれば、カスタマイズされた hashCode() メソッドとquals() メソッドをオーバーライドすることで、特定の特別なニーズを実現できます。

distinct() メソッドは次のように宣言されます。

Stream<T> distinct();

1.1 String リストの重複排除の場合

String クラスは、equals() メソッドと hashCode() メソッドをオーバーライドしているため、したがって、重複を正常に削除できます。

@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();

}

結果は次のとおりです:

重複排除前: AABBC
重複排除後: ABC

1.2 エンティティ クラス リストの重複排除

注: コードでは、Lombok プラグインの @Data アノテーションを使用します。これにより、equals() メソッドと 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));
  }

結果は次のとおりです:

重複排除前: [{"stuNo":"001","name":"Tom"},{"stuNo":" 002" ,"name":"Mike"},{"stuNo":"001","name":"Tom"}]
重複排除後: [{"stuNo":"001","name": " Tom"},{"stuNo":"002","name":"Mike"}]

2. Lista87fdacec66f0909fc0757c19f2d2b1d# 内のオブジェクトの特定の属性に基づいて重複を削除します。

# #2.1 新しいリストを作成します

@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));
  }

結果は次のようになります:

重複排除前:[{"stuNo":"001","name":") Tom"},{" stuNo":"001","name":"Tom"},{"stuNo":"003","name":"Tom"}]

重複を削除した後: [{" stuNo":"001 ","name":"Tom"},{"stuNo":"003","name":"Tom"}]
名前に基づいて重複を削除した後: [{"stuNo" :"001","name ":"Tom"}]

2.2 filter() メソッドを通して

最初に Stream.filter() のパラメーターとしてメソッドを作成します。 、戻り値の型は Predicate です。原則として、要素を Set に追加できるかどうかを判断するには、コードは次のとおりです:

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

次のように使用します:

@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));
  }

結果は次のとおりです。次のように:

重複排除前:[{" stuNo":"001","name":"Tom"},{"stuNo":"001","name":"Tom" },{"stuNo":"003","name":"Tom" }]

個別の重複排除後: [{"stuNo":"001","name":"Tom"},{"stuNo" :"003","name":"Tom"}]
名前に基づいて重複を削除した後: [{"stuNo":"001","name":"Tom"}]

以上がJava 8 の Stream を使用してリストの重複排除を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。