删除属于同一组的数组元素只留下该组中的一个?

时间:2014-04-15 19:47:10

标签: java arrays

我有一个对象myArray[]的数组MyThing,其中包含X个元素。我需要删除属于同一组的元素,但要留下每个组的一个代表。

MyThing类有一个字段groupId

public class MyThing {

  private int groupId;
  //...other fields

  public int getGroupId(){return groupId;}
  //getter and setter
}

所以我必须比较groupId数组元素的整数值(myArray[x].getGroupId())和删除属于同一组的所有元素,除了数组中的第一个这样的元素。< / p>

这样我将获得一组独特的元素,同一组中只有1个。例如,如果我在纯化后有一个包含a.getGroupId()=1, b.getGroupId()=2, c.getGroupId()=1的数组,则该数组将仅包含{a,b},并且c将被删除,因为它与a属于同一组。

因为这是自定义对象,所以我无法使用Set<T>

有什么想法吗?

PS。如果我清楚地解释了这一点,请告诉我,因为它有点令人困惑。

6 个答案:

答案 0 :(得分:1)

使用TreeSet和自定义Comparator类来检查您的对象,并将同一组中的两个视为相等。

http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html

算法psuedocode:

Create TreeSet
Add all array elements to TreeSet
Convert TreeSet back to array

有关示例实施:see Martin's answer

答案 1 :(得分:1)

按定义设置的集合不包含任何重复项。一个集合通过使用对象equals()/ compareTo(..)方法或使用比较器来确定两个项目是否相似。如果您只需要集合中的唯一项目,那么实现Comparable接口并覆盖equals()就是您想要做的。但是在你的情况下,你只对独特组中的对象感兴趣,所以最好为场合创建一个自定义比较器,然后将其提供给Set,告诉它使用它,而不是“自然排序”。

Set<MyThing> myThings = new TreeSet<>(new Comparator<MyThing>() {
        @Override
        public int compare(MyThing  o1, MyThing  o2)
        {
            return o1.getGroupId() - o2.getGroupId(); 
        }
    }); 
myThings.addAll(Arrays.asList(myArray));

创建集后,使用方便的方法addAll(..)将整个数组添加到其中。

(比较器如何对对象进行排序完全取决于您自己决定。)

答案 2 :(得分:1)

您可以遍历数组并使用地图来跟踪已经发生的ID。然后如果已经将一个添加到集合中,则将其从数组中删除:

Set<Integer> uniqueIDs = new HashSet<Integer>();

for(MyThing thing : MyThings){
    int groupID = thing.getGroupId();

    if(!uniqueIDs.add(groupID)){
        // DUPLICATE, REMOVE IT
    }
}

答案 3 :(得分:1)

刚刚重写了Martin的解决方案,因为比较器坏了,它可能会溢出

Set<MyThing> myThings = new TreeSet<>(new Comparator<MyThing>() {
  @Override
  public int compare(MyThing  o1, MyThing  o2) {
    return Integer.compare(o1.getGroupId(), o2.getGroupId()); 
  }
}); 
myThings.addAll(Arrays.asList(myArray));

答案 4 :(得分:0)

为什么不试试(半伪代码):

List<Integer> uniqGroups = new ArrayList<Integer>();
for (int i = 0; i < myArray.length; i++) {
    int groupId = myArray[i].getGroupId();

    if (!uniqGroups.contains(groupId)) {
        // Hasn't been seen before, keep around
        uniqGroups.add(groupId);
    }
    else {
        // Already seen, remove or otherwise clean up the array
        myArray[i] = null;
    }
}

答案 5 :(得分:-1)

由于您只需要通过groupId区分对象,您可以覆盖类中的 hashCode() equals()方法:

class MyThing {
    private int groupId;
    public int getGroupId(){return groupId;}

    // new code to add...
    @Override
    public int hashCode() {
        return groupId;
    }
    @Override
    public boolean equals(Object o) {
        return (o instanceof MyThing
             && (groupId == ((MyThing)o).groupId));
    }
}

然后,使用 HashSet&lt; MyThing&gt; 类删除myArray中包含重复的groupId的MyThing对象:

myArray = new HashSet<MyThing>(Arrays.asList(myArray)).toArray(new MyThing[0]);