简体   繁体   English

从 HashMap 条目列表中删除重复项

[英]Remove Duplicates from List of HashMap Entries

I have a List<HashMap<String,Object>> which represents a database where each list record is a database row.我有一个List<HashMap<String,Object>>代表一个数据库,其中每个列表记录都是一个数据库行。

I have 10 columns in my database.我的数据库中有 10 列。 There are several rows where the values of 2 particular columns are equals.有几行的 2 个特定列的值相等。 I need to remove the duplicates from the list after the list is updated with all the rows from database.在使用数据库中的所有行更新列表后,我需要从列表中删除重复项。

What is the efficient way?什么是有效的方法?

FYI - I am not able to do distinct while querying the database, because the GroupName is added at a later stage to the Map after the database is loaded.仅供参考 - 我在查询数据库时无法执行不同的操作,因为在加载数据库后,稍后将 GroupName 添加到Map And since Id column is not primary key, once you add GroupName to the Map .由于 Id 列不是主键,因此一旦将 GroupName 添加到Map You will have duplicates based on Id + GroupName combination!您将有基于 Id + GroupName 组合的重复项!

Hope my question makes sense.希望我的问题有意义。 Let me know if we need more clarification.如果我们需要更多说明,请告诉我。

  1. create a Comparator that compares HashMaps, and compares them by comparing the key/value pairs you are interested in.创建一个比较 HashMaps 的 Comparator,并通过比较您感兴趣的键/值对来比较它们。
  2. use Collections.sort(yourlist, yourcomparator) ;使用Collections.sort(yourlist, yourcomparator) ;
  3. Now all maps that are similar to each other, based on your comparator, are adjacent in the list.现在,基于您的比较器,所有彼此相似的地图在列表中都是相邻的。
  4. Create a new list.创建一个新列表。
  5. Iterate through your first list, keeping track of what you saw last.遍历您的第一个列表,跟踪您最后看到的内容。 If the current value is different than the last, add this to your new list.如果当前值与上一个不同,请将其添加到新列表中。
  6. You new list should contain no duplicates according to your comparator.根据您的比较器,您的新列表不应包含重复项。

The cost of iterating through the list is O(n).遍历列表的成本是 O(n)。 Sorting is O(n log n).排序是 O(n log n)。 So this algorithm is O(n log n).所以这个算法是 O(n log n)。

We could also sort on-the-fly by using a TreeSet with that comparator.我们还可以通过使用带有该比较器的 TreeSet 进行动态排序。 Inserts are O(log n).插入是 O(log n)。 And we have to do this n times.我们必须这样做n次。 So we get O(n log n).所以我们得到 O(n log n)。

I was having same condition, after lot of search, finally below solution worked for me.我遇到了同样的情况,经过大量搜索,最终以下解决方案对我有用。

  1. Create POJO, override equal () & hashCode ().创建POJO,覆盖equal () & hashCode ()。
  2. equality should be on all data members with .equal comparison.相等性应该在所有具有 .equal 比较的数据成员上。
  3. Hashcode calculated as Objects.hash(filed1, field2, ...) ;哈希码计算为Objects.hash(filed1, field2, ...) ;
  4. Iterate over list and construct POJO object and add it to HashSet遍历列表并构造POJO 对象并将其添加到 HashSet

Below is code -下面是代码——

/* (non-Javadoc)
 * @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(Object obj) {
    if( this == obj) {
        return true;
    }
    if( null == obj || getClass() != obj.getClass()) {
        return false;
    }

    Pojo rest = (Pojo) obj;
    return field1.equals(rest.field1) && field2.equals(rest.field2) && field3.equals(rest.field3); 
}

/* (non-Javadoc)
 * @see java.lang.Object#hashCode()
 */
@Override
public int hashCode() {
    return Objects.hash(field1, field2, field3);
}

Set<Pojo> pathSet = new HashSet<>();
//Iterate over list and construct pojo object here
Pojo pojo = new Pojo(value1, value2, value3)
pathSet.add(pojo)

Thanks,谢谢,

I have taken an Employee class and created Map with Integer,Employee object as key-value pair here is my Map我已经学习了一个 Employee 类并使用 Integer,Employee 对象创建了 Map 作为键值对,这里是我的 Map

Map<Integer,Employee> map = new HashMap<Integer,Employee>();

Employee class is a bean class and it has properties like name,id,designation; Employee 类是一个 bean 类,它具有 name、id、designation 等属性; map allow unique keys. map 允许唯一键。 but if you don't want to allow duplicate values in your map you have to over ride equals method in bean class.但是如果你不想在你的地图中允许重复的值,你必须在 bean 类中覆盖 equals 方法。

@Override
public boolean equals(Object object){
    if (object == null) return false;
    if (object == this) return true;
    if (this.getClass() != object.getClass())return false;
    Employee employee = (Employee)object;
    if(this.hashCode()== employee.hashCode())return true;
   return false;
}  

and while adding key-value to Map you have to use contains method在向 Map 添加键值时,您必须使用 contains 方法

if(!map.containsValue(map.get(id))){
   map.put(id,employee);
}

containsValue internally calls equals() method and hence you over ride equals method it will check every value(object) with previous objects and if hash codes are same it returns true means both are same objects. containsValue内部调用equals()方法,因此您可以使用 equals 方法,它将检查每个值(对象)与以前的对象,如果哈希码相同,则返回 true 表示两者都是相同的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM