java 获取 List 的唯一元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14435305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:15:44  来源:igfitidea点击:

Getting unique elements of List

javalistarraylistsethashset

提问by HkFreaKuser1673718

all I have list containing Duplicate values I want somehow to get only Unique values from it and store it another list or set.So that I can perform some operation on it. My code:

所有我有包含重复值的列表我想以某种方式只从中获取唯一值并将其存储另一个列表或集合。这样我就可以对其执行一些操作。我的代码:

{
        List<Integer[]> list1 = new ArrayList<Integer[]>();
          list1.add(new Integer[] { 1,10 });
            list1.add(new Integer[] { 1,10 });
            list1.add(new Integer[] { 1,10 });      
            list1.add(new Integer[] { 2,10 });
            list1.add(new Integer[] { 1,10 });
            list1.add(new Integer[] { 3,10 });

        for(int i=0;i<list1.size();i++)
        {
            System.out.println("I - 0 :"+list1.get(i)[0]+"\t I - 1 :"+list1.get(i)[1]+"\n");
        }

        Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);

        for(Integer[] number: uniquelist){
              System.out.println(number[0]+"\t"+number[1]);
            }
    }    

I want the result {1,10;2,10;3,10}to be in separate list.When i googled I got to know for unique we should use set as in Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);But after doing this I dont know how to access each elements Thanks in advance

我希望结果{1,10;2,10;3,10}在单独的列表中。当我用谷歌搜索时,我知道我们应该使用 set as inSet<Integer[]> uniquelist = new HashSet<Integer[]>(list1);但是这样做之后我不知道如何访问每个元素提前谢谢

Output:
1   10
2   10
1   10
3   10
1   10
1   10

回答by Rohit Jain

You won't get the result you want using the normal Setapproach. As your Listcontains Integer[], and then won't be considered unique by default. All the array objects are distinct. So, your Setwill contain the same elements as your list. However, you can define your Custom Comparator, and use it with a TreeSetconstructor.

使用正常Set方法不会得到您想要的结果。由于您的Listcontains Integer[],然后默认情况下不会被视为唯一的。所有数组对象都是不同的。因此,您Set将包含与列表相同的元素。但是,您可以定义您的Custom Comparator,并将其与TreeSet构造函数一起使用。

Another way of doing it can be, define a method contains(List<Integer[]> list, Integer[] value), which checks whether your list contains that array. Define a list named uniqueList. Now, iterate over your original list, and then for each value, call containsmethod passing uniqueListand that value, as parameters.

另一种方法是,定义一个方法contains(List<Integer[]> list, Integer[] value),它检查您的列表是否包含该数组。定义一个名为 的列表uniqueList。现在,迭代您的原始列表,然后对于每个值,调用contains方法传递uniqueList和那个value,作为参数。

Here's how your containsmethod would look like: -

您的contains方法如下所示:-

public static boolean contains(List<Integer[]> list, Integer[] value) {
    for (Integer[] arr: list) {
        // We can compare two arrays using `Arrays.equals` method.
        if (Arrays.equals(arr, value)) {
            return true;
        }
    }
    return false;
}

So, you can see that, checking for containment is not the same as, how it would look for just Integer.

因此,您可以看到,检查遏制与仅查找Integer.

Now, from your mainmethod, use this code: -

现在,从您的main方法中,使用以下代码:-

List<Integer[]> unique = new ArrayList<Integer[]>();

for (Integer[] arr: list1) {
    // Use your method here, to test whether this value - `arr` 
    // is already in `unique` List or not. If not, then add it.
    if (!contains(unique, arr)) {
        unique.add(arr);
    }
}

for (Integer[] arr: unique) {
    System.out.println(arr);
}

回答by Dan D.

I would rather use a Setimplementation in this case. Use LinkedHashSetif you want your elements to be ordered.

Set在这种情况下,我宁愿使用实现。使用LinkedHashSet,如果你希望你的元素进行排序。

You could declare a class IntegerPair to hold your pairs:

您可以声明一个 IntegerPair 类来保存您的对:

class IntegerPair {
  private int key;

  private int value;

  public IntegerPair(int k, int v) {
    key = k;
    value = v;
  }

  public int getKey() {
    return key;
  }

  public int getValue() {
    return value;
  }

  public int hashCode() {
    return key * value;
  }

  public boolean equals(Object o) {
    if (!(o instanceof IntegerPair)) {
      return false;
    }
    IntegerPair other = (IntegerPair) o;
    return key == other.key && value == other.value;
  }
}

Declare it this way:

这样声明:

Set<IntegerPair> set = new LinkedHashSet<IntegerPair>();

Instead of putting new Integer[]values, just do set.add(new IntegerPair(1, 10));

而不是把new Integer[]值,只是做set.add(new IntegerPair(1, 10));

You can loop through your elements using the foreach approach:

您可以使用 foreach 方法遍历元素:

for (IntegerPair value : set) {
  System.out.println(value.getKey() + "  =  " + value.getValue());
} 

回答by Sumit Singh

Problem :

问题 :

Obviously it will return in same manner in witch its returning because setis..

显然它会以相同的方式返回,因为set是..

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

不包含重复元素的集合。更正式地说,集合不包含一对元素 e1 和 e2,使得 e1.equals(e2),并且最多包含一个空元素。正如其名称所暗示的那样,该接口对数学集合抽象进行建模。

But in your case you are adding in list like ..

但是在您的情况下,您正在添加列表,例如 ..

List<Integer[]> list1 = new ArrayList<Integer[]>();
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 1,10 });      
list1.add(new Integer[] { 2,10 });
list1.add(new Integer[] { 1,10 });
list1.add(new Integer[] { 3,10 });

Here new Integer[] { 1,10 }every time is a different object so that its adding all the objects.

这里new Integer[] { 1,10 }每次都是一个不同的对象,以便它添加所有对象。

Solution :
Simply the solution is you have to take care that in list no duplicate(according to your requirement) Integer array can add.

解决方案:
简单的解决方案是您必须注意列表中没有重复的(根据您的要求)整数数组可以添加。

So you can create one method that can check weather if that Array is already in list that don't add it , if not in list then add that.

因此,您可以创建一种方法来检查天气,如果该 Array 已经在不添加它的列表中,如果不在列表中则添加它。

public void addUnique(List<Integer[]> list, Integer[] newValue) {
    for (Integer[] array: list) {
        //Compare two arrays using `Arrays.equals` method.
        if (Arrays.equals(array, newValue)) {
            list.add(newValue)
        }
    }
}

add call it like following..

添加调用它如下..

List<Integer[]> list1 = new ArrayList<Integer[]>();
addUnique(list1  , new Integer[] { 1,10 });
addUnique(list1  , new Integer[] { 1,10 });
addUnique(list1  , new Integer[] { 1,10 });
addUnique(list1  , new Integer[] { 2,10 });
addUnique(list1  , new Integer[] { 1,10 });
addUnique(list1  , new Integer[] { 3,10 });

回答by Jigar Joshi

You can access elements by Iteratoror by using for each loop

您可以通过Iterator或使用 for 每个循环访问元素

for(Integer number: setOfNumbers){
  System.out.println(number);
}

回答by AlexR

Put them into set using your custom comparator like following:

使用您的自定义比较器将它们放入设置中,如下所示:

new TreeSet(list1, new Comparator<Integer[]>() {
    public int compare(Integer[] one, Integer[] two) {
        int n = one.length;
        for (int i = 0;  i < n;  i++) {
              int comp = one.compareTo(two);
              if (comp != 0) {
                   return comp;
              }
        }
        return 0;
    }
});

Pay attention that I used TreeSetthat can accept custom comparator. It is because you are dealing with arrays. If however you define your own class that holds 2 int values you can make it to implement equals()and hashCode()that allows using any Set implementation.

注意我使用的TreeSet可以接受自定义比较器。这是因为您正在处理数组。但是,如果您定义自己的包含 2 个 int 值的类,则可以使其实现equals()hashCode()允许使用任何 Set 实现。

回答by SANN3

Try Tablecollection in Google-guava.

Google-guava 中尝试集合。

Example :

例子 :

Table<Integer, Integer, Integer[]> sampleTable = HashBasedTable.create();
sampleTable.put(1, 10, new Integer[] { 1,10 });
sampleTable.put(2, 10, new Integer[] { 2,10 });
sampleTable.put(1, 10, new Integer[] { 1,10 });

So it will overwrite the duplicate values. Finally you have only unique values.

所以它会覆盖重复的值。最后,您只有唯一的值。

回答by Cedias

the Integer[] numberin your for loop is an array. to get the values inside you have to use number[index]instruction. to do that you can either do a classic while or for loop using a variable as an index

Integer[] number你的for循环是一个数组。要获得里面的值,你必须使用number[index]指令。为此,您可以使用变量作为索引执行经典的 while 或 for 循环

for(int i=0;i<number.length;i++) {
...
}

or a foreach loop:

或 foreach 循环:

for(Integer num : number){
...
}

回答by nullptr

This may help you...

这可能会帮助你...

public static void main(String [] args){
    Set<Integer []> set = new TreeSet<Integer []>(new Comparator<Integer[]>(){
        public int compare(Integer[] o1, Integer[] o2) {
            if(o1.length == o2.length){
                for(int i = 0; i < o1.length; i++){
                    if(o1[i] != o2[i]){
                        return -1;
                    }
                }
                return 0;
            }
            return -1;
        }
    });

    set.add(new Integer[]{1,2});
    set.add(new Integer[]{1,2});
    set.add(new Integer[]{1,2});
    set.add(new Integer[]{1,3});

    int j = 0;
    for(Integer[] i: set){
        System.out.println("\nElements: "+j);
        j++;
        for(Integer k : i){
            System.out.print(k+" ");
        }
    }
}

You need to use Comparatorto compare two elements of same. As we don't have comparator for Array, Set will use actual object to compare.. using comparator you will have to tell set that this two arrays are same and do not add other same array

您需要使用Comparator来比较两个相同的元素。由于我们没有 Array 的比较器,Set 将使用实际对象进行比较。