从任何数据集合中删除重复的通用方法

时间:2018-03-29 08:33:42

标签: java

我必须从随机数据集中删除重复的行。
数据由api作为JSONArray对象从数据库中检索,并且可以出现任何数量/类型的列。

例如,在一种情况下,它可能像:

TimeStamp              Id   Value   Person
---------             ----  -----   ------
01-01-2018 14:22:16    12    0.3     Mac
01-01-2018 14:32:16    11    0.1     Arya
01-01-2018 14:32:16     2    0.8     Stephen
01-01-2018 14:32:16    11    0.1     Arya

在另一种情况下,它可能类似于:

Department     Floor    Budget
---------      -----   --------
  Sales         26      100000
 Finance        25      200000 
 Finance        25      200000
Production       1      9000000

我需要编写一个可以从任何此类集合中删除重复的泛型方法。

幸运的是,在大多数的情况下,重复的行可以用2或3列来标识。 (例如,在第一个示例集中,如果TimeStampId相同,则可以将该行视为重复行)

目前,我只能想到这样做的天真方式:

写一个方法,

  1. 将输入数据和标识重复行的列列表作为参数
  2. 对于每一行,创建一个字符串,该字符串是唯一行标识符列
  3. 的concat
  4. 继续将上述字符串添加到集合中。
  5. 对于任何行,如果上面的字符串已经在集合中(重复行),则继续,否则将该行添加到输出数组。
  6. 基本上,写一个像:

    这样的方法
    public JSONArray removeDuplicateRows(JSONArray input,List<String> dupCriteriaColumns){
    
        JSONArray opAray = new JSONArray();
        HashSet<String>  uniqueRows = new HashSet<String>();
    
        for (int i = 0; i < input.length(); i++) {
            StringBuffer uniqueColString = new StringBuffer();
            JSONObject currRow = input.getJSONObject(i); 
    
            for (String column : dupCriteriaColumns){
                uniqueColString.add(currRow.getString(column));                         
            }
    
            if(uniqueRows.contains(uniqueColString)){
                // Duplicate row
                continue;
            }else{
                opAray.addJSONObject(currRow);
                uniqueRows.add(uniqueColString);
            }       
    
        }
        return opAray;
    
    }
    


    当然如果“唯一行标识符列”的数量太多,我最终会得到大型的String对象,这个解决方案会很糟糕。

    编辑1: 我不想为每个数据集创建POJO,因为数据集的类型太多,它们的结构经常变化,并且经常添加/删除新类型。

    任何人都可以建议我一个更好的主意/逻辑吗?

2 个答案:

答案 0 :(得分:4)

我会浏览我的实体并添加正确的equals()和hashCode()逻辑(基于我想要唯一的字段)。

然后在检索实体时,我会在集合中检索它们。

它将会有效地删除集合中的重复项,因为集合使用equals和hashCode来保留唯一对象。

答案 1 :(得分:0)

如果您控制数据检索,那么我建议删除数据库级别的重复项。

如果没有,我建议为每种类型的数据编写特定的方法,即将JSONArray转换为特定类型,并处理那里的重复数据。