簡體   English   中英

如何從 Java 中的列表集中刪除重復項

[英]How to remove duplicates from Set of list in Java

我有一組列表,無論每個列表中元素的順序如何,我都想從中刪除重復項,如下所示:

我有這個作為輸入[[-1,-1,2],[0,-1,1],[1,-1,0],[2,-1,-1],[-1,2,-1],[-1,1,0],[0,1,-1],[-1,0,1],[1,0,-1]]

當我使用Set<Set>來優化我的元素時,它完成了部分工作,但我得到[[1,-1,0],[-1,2]]這是邏輯,因為內部 Set 優化了[-1,-1,2]

當我嘗試使用Set<List>我無法優化我的元素,這讓我變成了[[-1,-1,2],[0,-1,1],[1,-1,0],[2,-1,-1],[-1,2,-1],[-1,1,0],[0,1,-1],[-1,0,1],[1,0,-1]]

那么我如何才能設法優化重復項並保持我得到的三元組完整無缺呢?

先感謝您。

我認為您可以使用排序來使使用 Set 和 List 按照您指定的方式工作:

import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

class Main {
    
    public static void main(String[] args) {
        int[][] arrayWithDuplicates = new int[][] { { -1, -1, 2 }, { 0, -1, 1 }, { 1, -1, 0 }, { 2, -1, -1 },
                { -1, 2, -1 }, { -1, 1, 0 }, { 0, 1, -1 }, { -1, 0, 1 }, { 1, 0, -1 } };
        System.out.printf("arrayWithDuplicates = %s%n", Arrays.deepToString(arrayWithDuplicates));
        int[][] arrayWithoutDuplicates = getArrayWithoutDuplicates(arrayWithDuplicates);
        System.out.printf("arrayWithoutDuplicates = %s%n", Arrays.deepToString(arrayWithoutDuplicates));
    }

    public static int[][] getArrayWithoutDuplicates(int[][] array) {
        List<int[]> listWithoutDuplicates = new ArrayList<>();
        Set<List<Integer>> seenSubLists = new HashSet<>();
        for (int[] ints : array) {
            List<Integer> sortedInts = Arrays.stream(ints).boxed().sorted().collect(Collectors.toList());
            if (!seenSubLists.contains(sortedInts)) {
                listWithoutDuplicates.add(ints);
                seenSubLists.add(sortedInts);
            }
        }
        return listWithoutDuplicates.toArray(new int[listWithoutDuplicates.size()][]);
    }

}

輸出:

arrayWithDuplicates = [[-1, -1, 2], [0, -1, 1], [1, -1, 0], [2, -1, -1], [-1, 2, -1], [-1, 1, 0], [0, 1, -1], [-1, 0, 1], [1, 0, -1]]
arrayWithoutDuplicates = [[-1, -1, 2], [0, -1, 1]]
    final Set<List<Integer>> sortedLists = new HashSet<>();
    Set<List<Integer>> newLists = lists.stream()
            .map(integers -> {
                List<Integer> sorted = integers.stream().sorted().collect(Collectors.toList());
                if (sortedLists.contains(sorted)) {
                    return null;
                }
                sortedLists.add(sorted);
                return integers;
            })
            .filter(Objects::nonNull)
            .collect(Collectors.toSet());

您可以創建一個類來表示您的集合元素並賦予它們您想要的行為。 也就是說,如果兩個元素包含相同的整數而不管順序如何,則它們是相等的。

import java.util.Arrays;
public class IntList extends Object {
    // I will keep the original array but you can just sort it in place if that makes sense
    private int[] array; // The orignal array
    private int[] sortedArray; // Sorted copy of the original array
    public IntList( int[] array ) {
        this.array = array;
        this.sortedArray = array.clone();
        Arrays.sort( this.sortedArray );
    }
    @Override
    public boolean equals( Object o ) {
        // This object is equal to another if they are:
        //   the same instance or instances of this class with equal sorted arrays
        boolean result;
        if ( o == this ) {
            result = true;
        } else {
            if ( ! ( o instanceof IntList ) ) {
                result = false;
            } else {
                IntList other = ( IntList ) o;
                result = Arrays.equals( this.sortedArray, other.sortedArray );
            }
        }
        return result;
    }
    @Override
    public int hashCode() {
        // Used by HashSet
        return Arrays.hashCode( this.sortedArray );
    }
    @Override
    public String toString() {
        return Arrays.toString( this.sortedArray );
    }
}

然后你可以用這個類的元素構造一個 Set:

import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;

public class main {
    public static void main(String[] args) {
        int[][] input = new int[][] { { -1, -1, 2 }, { 0, -1, 1 }, { 1, -1, 0 }, { 2, -1, -1 },
                { -1, 2, -1 }, { -1, 1, 0 }, { 0, 1, -1 }, { -1, 0, 1 }, { 1, 0, -1 } };

        System.out.printf("input = %s%n", Arrays.deepToString(input));

        Set<IntList> set = new HashSet<IntList>();
        for( int[] currIntArray: input ) {
            IntList list = new IntList( currIntArray );
            set.add( list );

        }
        System.out.printf( "output = %s%n", set.toString());
    }
}

結果

input = [[-1, -1, 2], [0, -1, 1], [1, -1, 0], [2, -1, -1], [-1, 2, -1], [-1, 1, 0], [0, 1, -1], [-1, 0, 1], [1, 0, -1]]
output = [[-1, -1, 2], [0, -1, 1]]

您這樣做的方式實際上取決於您的問題域的更大范圍。 我認為您不太可能真的想要一個名為 IntList 的公共類,但您可能會將它包含在您自己的 Set 實現中,或者您模型中的其他地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM