Java 从arraylist中删除重复项
我正在尝试从arraylist中删除重复的对象 见下面的代码:Java 从arraylist中删除重复项,java,arraylist,Java,Arraylist,我正在尝试从arraylist中删除重复的对象 见下面的代码: ArrayList<Customer> customers=new ArrayList<Customer>(); for(int i=0;i<accounts.size();i++){ customers.add(accounts.get(i).getCustomer()); } for(int i=0;i<customers.size();i++){
ArrayList<Customer> customers=new ArrayList<Customer>();
for(int i=0;i<accounts.size();i++){
customers.add(accounts.get(i).getCustomer());
}
for(int i=0;i<customers.size();i++){
for(int j=i+1;j<customers.size();j++){
if(customers.get(i).getSocialSecurityNo().compareTo(customers.get(j).getSocialSecurityNo())==0){
if(customers.get(i).getLastName().compareToIgnoreCase(customers.get(j).getLastName())==0){
if(customers.get(i).getFirstName().compareToIgnoreCase(customers.get(j).getFirstName())==0){
customers.remove(j);
}
}
}
}
}
ArrayList客户=新建ArrayList();
对于(int i=0;i是您的int j=i+1
造成了问题。您需要在每次迭代中使用客户列表的最后一个值进行测试。在将客户添加到上述循环的列表之前,为什么不检查
if(!cutomers.contains(accounts.get(i).getCustomer())
{
//add them if it doesn't contain
}
它应该可以避免您执行第二个循环
编辑:需要重写该方法。基本缺陷是,由于ListArray是可变的,一旦删除一个元素,就必须重新调整索引
if(customers.get(i).getFirstName().compareToIgnoreCase(customers.get(j).getFirstName())==0){
customers.remove(j--);
}
还可以尝试从i循环中减去一:
for(int i=0;i<customers.size()-1;i++){
for(int j=i+1;j<customers.size();j++){
for(int i=0;icustomers=newarraylist(newhashset(customers))
确保正确执行equals和hashmethod删除项目后尝试添加j-->
。这将为您重新编制索引并解决问题
public static void removeDuplicates(ArrayList list) {
HashSet set = new HashSet(list);
list.clear();
list.addAll(set);
}
覆盖适当的equals和hashcode因此,关于正确执行此操作:
您的Customer对象应该有一个and方法来进行比较(或者您只需要为每个客户提供一个Customer对象,这意味着您的数据模型必须进行调整。然后默认的hashCode/equals就可以了)
如果您有此功能,可以将三个嵌套的ifs替换为一个:
if(customers.get(i).equals(customers.get(j)) {
customers.remove(j);
}
这还不能解决你的问题,但可以让你更清楚地看到它。如果
查看哪些对象与哪些其他对象进行了比较,您将看到每次删除后
对于列表中的对象,下一个对象的索引与刚才删除的对象的索引相同,
您不会将当前对象与它进行比较。正如前面所说,删除后的j--
将解决此问题
更高性能的解决方案是使用集合(保证不包含重复项)。
在您的情况下,一个HashSet
或LinkedHashSet
(如果您关心订单)
好的
然后,您的整个代码归结为:
Set<Customer> customerSet = new HashSet<Customer>();
for(Account acc : accounts){
customerSet.add(acc.getCustomer());
}
List<Customer> customers = new ArrayList<Customer>(customerSet);
Set customerSet=new HashSet();
会计科目(会计科目:会计科目){
customerSet.add(根据getCustomer());
}
列表客户=新阵列列表(customerSet);
如果你真的不需要一个列表(即索引访问),只需简单地修改最后一行即可
使用集合。正如其他人所提到的,我的第一个想法是使用集合。另一种方法是使用Java版本的foreach,而不是使用索引。一般方法:
public static ArrayList removeDuplicates(ArrayList origList) {
ArrayList newList = new ArrayList();
for (Object m : origList) {
if (!newList.contains(m)) {
newList.add(m);
}
}
return newList;
}
在测试中,我只使用了字符串;为了类型安全,我建议在适当的地方将Customer插入到代码中。下面的代码对我很有用。试试看。您可以根据自己的喜好操作compare方法
ArrayList客户=……;
Set customerlist=新树集(新比较器(){
将其插入到一个集合中可能重复-如果您遵循tylermac的建议(这是一个好建议)。请确保覆盖equals()和hashCode()方法。@RMT,我曾经提出过这个建议,并且是许多负面意见的焦点。:)@mre这是真的,它不是最好的使用方法,我认为它应该比下面的第二和第三个循环更好。(只是我的观点:))有很多更好的方法来解决这个问题,但这并不能回答他/她的问题。他/她的算法有什么问题吗?@RMT我尝试过这样做,但它似乎不起作用(int i=0;i@trs我忘了告诉你的是,你必须覆盖Equals方法。基本上,当(从我所知道的)客户是平等的if语句中的所有内容。j+1只是确保每个项都与自身进行比较。这就是迭代器发挥作用的地方。是的,迭代器总是更好!@Voo:迭代器在这里没有真正的帮助,你会在股票数组列表中得到ConcurrentModificationExceptions。@Paulo你可以用迭代器得到它,但是它看起来没有任何改善。所以是的,没有那么好。您应该将方法签名更改为removeDuplicates(集合列表)
(程序到接口,而不是具体的类)。因此,我想我不能将您的方法用于LinkedList
或任何其他非ArrayList集合。您只需复制粘贴该方法并接受另一个类类型。LinkedList
是Java集合框架中众多集合之一。请查看并查看“所有已知实现类”下的内容对于各种集合
实现。@Steve我不确定这与任何事情有什么关系。@nsfyn55 Java语言规范现在由Oracle驱动,因此通过使用Java,您将任由他们摆布。。。
@Override
public int compare(Customer c1, Customer c2) {
return c1.getSocialSecurityNo().compareTo(c2.getSocialSecurityNo());
}
});
customerlist.addAll(customers);
customers.clear();
customers.addAll(customerlist);