1

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

{
        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}在单独的列表中。当我用谷歌搜索时,我知道我们应该使用 set 作为唯一Set<Integer[]> uniquelist = new HashSet<Integer[]>(list1);但这样做之后我不知道如何访问每个元素提前谢谢

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

8 回答 8

4

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

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

您的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);
}
于 2013-01-21T09:06:39.657 回答
3

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());
} 
于 2013-01-21T09:04:37.313 回答
1

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

for(Integer number: setOfNumbers){
  System.out.println(number);
}
于 2013-01-21T09:03:50.363 回答
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 值的类,则可以使其实现equals()hashCode()允许使用任何 Set 实现。

于 2013-01-21T09:13:29.820 回答
1

问题 :

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

不包含重复元素的集合。更正式地说,集合不包含一对元素 e1 和 e2 使得 e1.equals(e2),并且最多包含一个空元素。正如它的名字所暗示的,这个接口模拟了数学集合抽象。

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

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 });
于 2013-01-21T09:29:02.413 回答
0

在Google-guava中尝试Table集合。

例子 :

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

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

于 2013-01-21T09:14:21.187 回答
0

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

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

或 foreach 循环:

for(Integer num : number){
...
}
于 2013-01-21T09:16:25.830 回答
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 这两个数组是相同的并且不要添加其他相同的数组

于 2013-01-21T09:20:26.007 回答