如何从Java列表中删除重复项
Posted
技术标签:
【中文标题】如何从Java列表中删除重复项【英文标题】:How to remove duplicates from Set of list in Java 【发布时间】:2021-12-13 14:38:04 【问题描述】:我有一组列表,我想从 无论每个列表中的元素顺序如何删除重复项,如下所示:
我有这个作为输入 [[-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]]
那么我怎样才能设法优化重复项并保持生成的三元组完好无损?
提前谢谢你。
【问题讨论】:
【参考方案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]]
【讨论】:
【参考方案2】: 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());
【讨论】:
【参考方案3】:您可以创建一个类来表示您的集合元素并为它们提供您想要的行为。也就是说,如果两个元素包含相同的整数而不考虑顺序,则它们相等。
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 实现中,或模型中的其他位置。
【讨论】:
以上是关于如何从Java列表中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章
java 82.从排序列表II(递归).java中删除重复项