获得List的独特元素

时间:2013-01-21 09:02:11

标签: java list arraylist set hashset

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

{
        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]);
            }
    }    

我希望结果{1,10;2,10;3,10}位于单独的列表中。当我用Google搜索时,我必须知道我们应该在Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);中使用set但是在执行此操作后我不知道如何访问每个元素提前致谢

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

8 个答案:

答案 0 :(得分:3)

使用普通Set方法,您无法获得所需的结果。由于您的List包含Integer[],因此默认情况下不会被视为唯一身份。所有数组对象都是不同的。因此,您的Set将包含与列表相同的元素。但是,您可以定义Custom Comparator,并将其与TreeSet构造函数一起使用。

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

以下是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;
}

因此,您可以看到,检查包含与仅查找Integer的方式不同。

现在,从您的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);
}

答案 1 :(得分:2)

在这种情况下,我宁愿使用Set实现。如果您想要订购元素,请使用LinkedHashSet

你可以声明一个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;
  }
}

以这种方式声明:

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

不要输入new Integer[]值,只需执行set.add(new IntegerPair(1, 10));

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

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

答案 2 :(得分:1)

您可以按Iterator或使用每个循环

来访问元素
for(Integer number: setOfNumbers){
  System.out.println(number);
}

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

问题:

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

  

不包含重复元素的集合。更正式地说,集合不包含元素对e1和e2,使得e1.equals(e2)和至多一个null元素。正如其名称所暗示的,该界面对数学集抽象进行建模。

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

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

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

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

因此,您可以创建一个可以检查天气的方法,如果该数组已经在列表中而不添加它,如果不在列表中,则添加该数据。

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

添加如下的调用..

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

答案 5 :(得分:0)

Table中尝试Google-guava收藏。

示例:

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

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

答案 6 :(得分:0)

for循环中的Integer[] number是一个数组。获取内部值必须使用number[index]指令。要做到这一点,你可以使用变量作为索引来执行经典while或for循环

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

或foreach循环:

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

答案 7 :(得分:0)

这可能对你有所帮助......

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+" ");
        }
    }
}

您需要使用Comparator来比较相同的两个元素。由于我们没有Array的比较器,Set将使用实际对象进行比较..使用比较器你必须告诉set这两个数组是相同的并且不添加其他相同的数组