リスト重複排除 + Java8-Stream リスト内の特定のフィールドに基づく重複排除

リスト重複排除 + Java8-Stream ストリーム操作 リスト重複排除および指定フィールド重複排除

新しいリスト配列を作成します。

List list = new ArrayList(); 
list.add(26); 
list.add(39); 
list.add(39); 
list.add(39); 
list.add(39); 
list.add(5); 
list.add(40); 
list.add(39); 
list.add(25); 
System.out.println(list); 

方法 1: 新しい Java8 機能ストリームを使用してリストの重複を除去する [一般的に使用される]

注: オブジェクトを重複排除する場合、単一の重複排除ではなく、同じオブジェクト内のすべてのフィールドのみを重複排除できます。

List newList = list.stream().distinct().collect(Collectors.toList()); 
System.out.println(“java8新特性stream去重:”+newList); 
list.add(39); 

方法 3: 順序を乱すことなく、セットを判断して重複排除するように設定する

protected final <T> List<T> removeDuplicates(List<T> list) {
    
    
    return new ArrayList<>(new LinkedHashSet<>(list))
}

Java8-Stream ストリーム操作 リスト重複排除および指定フィールドの重複排除

方法 1: Java8-Stream ストリーム操作 リストの重複排除と指定されたフィールドの重複排除

stream の個別の重複排除メソッドは、Object.equals と Object.hashCode の 2 つのメソッドに基づいて、重複しているかどうかを判断します。
したがって、この機能を使用して、pojo の Object.equals と Object.hashCode の 2 つのメソッドを書き換えることで実現できます。

1. BookクラスのequalsメソッドとhashCodeメソッドを書き換え、名前を使用して比較が同じかどうかを判断し、ストリームのdistinctメソッドを使用して重複を排除します。

class Book {
    
    
    ...
 
    @Override
    public String toString() {
    
    
        return String.format("(%s,%s,%s)", id, name, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(createTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()));
    }
 
    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return Objects.equals(name, book.name);
    }
}
 
List<Book> distinctNameBooks1 = books.stream().distinct().collect(Collectors.toList());
System.out.println(distinctNameBooks1);

概要:equals メソッドと hashCode メソッドを書き換えて実際のニーズに応じて比較することにより、ストリームの個別のメソッドを直接使用して重複を排除でき、より便利です。オブジェクト クラスが不便であるか、変更できない場合があります。実装されているか、参照されているサードパーティ パッケージは変更できないため、この方法ではフィールドごとに柔軟に重複排除を行うことができません。

2. Collectors.collectingAndThen の Collectors.toCollection を通じて、TreeSet を使用してコンストラクター内のフィールドを指定します

フィールドの重複排除

List<ProjectInfoVo> vo = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ProjectInfoVo.class));
ArrayList<ProjectInfoVo> collect = vo.stream().collect(Collectors.collectingAndThen(
            Collectors.toCollection(() -> new TreeSet<>(
                    Comparator.comparing(p -> p.getProjectId()))), ArrayList::new));

複数フィールドの重複排除

List<ProjectInfoVo> vo = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ProjectInfoVo.class));
ArrayList<ProjectInfoVo> collect = vo.stream().collect(Collectors.collectingAndThen(
            Collectors.toCollection(() -> new TreeSet<>(
                    Comparator.comparing(p -> p.getProjectId()+";"+p.getMember()))), ArrayList::new));

概要:
stream が提供するメソッドを使用すると、コードは非常に簡潔になりますが、欠点は、重複排除効果は得られますが、リスト内の順序が変更され、一部のシーンでは順序を維持する必要があることです。

3. カスタム メソッド Comparator.comparing(p -> p.get***())

カスタム メソッド クラス - DifferentByKey

public class StreamUtils {
    
    

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

単一フィールド

List<ProjectInfoVo> acceptances = vo.stream()
	.filter(StreamUtils.distinctByKey(b -> b.getProjectId()))
	.collect(Collectors.toList());

複数のフィールド

List<ProjectInfoVo> acceptances = vo.stream()
	.filter(StreamUtils.distinctByKey(b -> b.getProjectId()))
	.filter(StreamUtils.distinctByKey(b -> b.getMember()))
	.collect(Collectors.toList());

概要: 重複排除メソッドをカプセル化して定義し、フィルター メソッドと組み合わせることで、フィールドごとに柔軟に重複排除を行い、元のリストの順序を維持できます。欠点は、HashMap が内部で定義されているため、ある程度のメモリを占有することです。追加のメソッド定義があります。

4. ストリームのフィルター メソッドを使用して重複排除を行い、重複排除メソッドを定義せず、外部で HashMap を作成します。

Map<Object, Boolean> map = new HashMap<>();
List<Book> distinctNameBooks4 = books.stream().filter(i -> map.putIfAbsent(i.getName(), Boolean.TRUE) == null).collect(Collectors.toList());
System.out.println(distinctNameBooks4);

概要: フィルター方式と連携して重複排除を実現しますが、別途の作成方式はなく、元のリストの順序を維持するために一時的に HashMap を定義しますが、ある程度のメモリを消費するのが欠点です。

おすすめ

転載: blog.csdn.net/sunrj_niu/article/details/128131331