Java 是否删除属于同一组的数组元素,只保留组中的1个?
我有一个数组Java 是否删除属于同一组的数组元素,只保留组中的1个?,java,arrays,Java,Arrays,我有一个数组myArray[]对象MyThing,其中包含X个元素。我需要删除属于同一组的元素,但每个组只留下一个代表 MyThing类有一个字段groupId public class MyThing { private int groupId; //...other fields public int getGroupId(){return groupId;} //getter and setter } 因此,我必须比较数组元素(myArray[x].getGroupI
myArray[]
对象MyThing
,其中包含X个元素。我需要删除属于同一组的元素,但每个组只留下一个代表
MyThing
类有一个字段groupId
public class MyThing {
private int groupId;
//...other fields
public int getGroupId(){return groupId;}
//getter and setter
}
因此,我必须比较数组元素(myArray[x].getGroupId()
)的groupId
整数值,并删除除数组中第一个这样的元素之外属于同一组的所有元素
通过这种方式,我将获得一个只有1个来自同一组的唯一元素的数组。例如,如果我有一个净化后a.getGroupId()=1,b.getGroupId()=2,c.getGroupId()=1
的数组,该数组将只包含{a,b}
,并且c
将被删除,因为它与a
属于同一组
因为这是自定义对象,所以无法使用Set
有什么想法吗
请让我知道,如果我解释清楚,因为它有点混乱 为什么不试试(这里是半伪代码):
List uniqGroups=new ArrayList();
for(int i=0;i
由于您只需要通过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类删除myArray中具有重复groupId的虚构对象:
myArray = new HashSet<MyThing>(Arrays.asList(myArray)).toArray(new MyThing[0]);
myArray=newhashset(Arrays.asList(myArray)).toArray(newmything[0]);
使用一个树集和一个自定义的比较器
类来检查对象,并将同一组中的两个对象视为相等
算法代码:
Create TreeSet
Add all array elements to TreeSet
Convert TreeSet back to array
对于示例实现:按定义设置的集合不包含任何重复项。集合通过使用objects equals()/compareTo(..)方法或使用比较器来确定两个项是否相同。如果您只希望集合中的项目是唯一的,那么实现Compariable接口并重写equals()就是您想要做的事情。但在您的情况下,您只对独特组中的对象感兴趣,因此最好为该场合创建一个自定义比较器,然后将其提供给集合,告诉集合使用它,而不是“自然排序”
Set myThings=新树集(新比较器(){
@凌驾
公共整数比较(神话o1,神话o2)
{
返回o1.getGroupId()-o2.getGroupId();
}
});
addAll(Arrays.asList(myArray));
创建集合后,使用便利方法addAll(..)将整个数组添加到集合中
(比较器如何对对象进行排序完全取决于您的决定。)您可以在数组中循环,并使用映射来跟踪哪些ID已经出现。然后,如果一个已添加到集合中,请将其从阵列中删除:
Set<Integer> uniqueIDs = new HashSet<Integer>();
for(MyThing thing : MyThings){
int groupID = thing.getGroupId();
if(!uniqueIDs.add(groupID)){
// DUPLICATE, REMOVE IT
}
}
Set uniqueid=new HashSet();
对于(虚构的事物:虚构){
int groupID=thing.getGroupId();
如果(!uniqueid.add(groupID)){
//复制,删除它
}
}
只需重写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));
Set myThings=新树集(新比较器(){
@凌驾
公共整数比较(神话o1,神话o2){
返回整数.compare(o1.getGroupId(),o2.getGroupId());
}
});
addAll(Arrays.asList(myArray));
您仍然可以使用仅存储组ID的集合,并使用该集合消除重复项。您可以使用一个映射,其中键是您的组ID,值是该组中的第一个数组元素。然后可以对映射键进行简单检查。使用Set
asLinkedHashSet
可以在一行中完成所有这一切;)Set obj=newlinkedhashset(Arrays.asList(myArray))代码>。有了它,你甚至可以保留物品的顺序,如果它像我的情况一样重要的话。天哪,这很有效。比詹姆斯的解决方案还要快。你能在这里编辑回复并解释逻辑吗。我以前从未使用过TreeSet
和Comparator
。@sandalone TreeSet是一个依赖于顺序的内置集合。由于正常的Set接口只关心相等而不关心顺序,所以TreeSet将比较器
作为构造函数参数,在插入过程中使用它而不是equals()
/hashcode()
。我已经知道了。与使用LinkedHasSet
保持秩序相同。我被重写的方法compare
弄糊涂了,该方法创建了两个MyThing
对象,并减去了其字段的值(在我的例子中是组id)。为什么?这样做的目的是什么?它使用您提供的方法(比较(神话a,神话b))来确定添加到它的对象的顺序/一致性。当to对象被确定为“相等”时,您提供的方法必须返回0。谢谢。检查@Martin的解决方案。如此优雅和快速,只需注意TreeSet已订购。不确定列表的整体顺序是否重要。是的,这里的顺序很重要。
Set<Integer> uniqueIDs = new HashSet<Integer>();
for(MyThing thing : MyThings){
int groupID = thing.getGroupId();
if(!uniqueIDs.add(groupID)){
// DUPLICATE, REMOVE IT
}
}
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));