【问题标题】:Get all duplicate objects from list从列表中获取所有重复的对象
【发布时间】:2020-03-11 12:59:50
【问题描述】:

我想创建一个新列表,其中仅包含输入列表中满足以下要求的交易:名称和代码应多次出现在输入列表中。 (参见示例。)项目和 ID 不相关。

输入列表

List<Transactions> transactionsList;
+----+------+----+-------+
| id | name |code|  item |
+----+------+----+-------+
| 1  | john | A1 | shoes |
| 2  | john | A1 | shirt |
| 3  | anon | A2 | shoes |
| 4  | anon | A2 | shoes |
| 5  |nymous| A3 | tie   |
+----+------+----+-------+

预期结果

+----+------+----+-------+
| id | name |code|  item |
+----+------+----+-------+
| 1  | john | A1 | shoes |
| 2  | john | A1 | shirt |
| 3  | anon | A2 | shoes |
| 4  | anon | A2 | shoes |
+----+------+----+-------+

我试过使用这个代码

List<Transactions> filteredTransactionList = new ArrayList<>();

for(Transactions transaction : transactionList){
    if (transactionList.stream().anyMatch(f -> 
        f.getName().equals(transaction .getName())) && 
        transactionList.stream().anyMatch(f -> f.getCode().equals(transaction .getCode())) ) {
                    filteredTransactionList.add(transaction );
    }
}

但似乎这段代码不起作用,因为当它发现自己在列表中时,if 条件将始终为真

如果可能的话,有什么方法可以在不使用 .stream 的情况下实现它? 有人说我可以使用地图来实现它,但我找不到这样做的方法。如果没有其他选择,使用任何东西都可以。

我必须为我的另一个 if() 函数保留 for 循环。

【问题讨论】:

    标签: java for-loop


    【解决方案1】:

    首先,您可以创建多个出现的对(名称,代码作为列表)列表。 然后使用此列表进行过滤。

    List<List<String>> moreThenOneOccurs = transactionsList.stream()
        .map(t -> Arrays.asList(t.getName(), t.getCode()))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
        .entrySet().stream().filter(e -> e.getValue() > 1)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
    
    List<Transactions> collect = transactionsList.stream()
        .filter(t -> moreThenOneOccurs.contains(Arrays.asList(t.getName(), t.getCode())))
        .collect(Collectors.toList());
    

    更新

    如果你想要没有流的东西:

    要创建重复列表,您可以check this

    Set<List<String>> moreThenOneOccurs = new HashSet<>();
    Set<List<String>> set1 = new HashSet<>();
    for (Transactions t : transactionsList) {
        if (!set1.add(Arrays.asList(t.getName(), t.getCode()))) {
            moreThenOneOccurs.add(Arrays.asList(t.getName(), t.getCode()));
        }
    }
    

    然后就可以进行过滤了:

    List<Transactions> filteredTransactionList = new ArrayList<>();
    for(Transactions t : transactionList){
        if (moreThenOneOccurs.contains(Arrays.asList(t.getName(), t.getCode()))) {
            filteredTransactionList.add(t);
        }
    }
    

    【讨论】:

      【解决方案2】:

      我对你使用的东西没有经验,这不是最快的方法,但我的回答对于初学者来说很容易理解。

      Use a double for loop. 
      for ( take a row to check if it has duplicates)
           for( go over all other rows to check if there is indeed a duplicate by comparing name 
                and code)
                If indeed a duplicate is found, print the row and go to the next. 
      

      您可以通过打印所有重复的行并在找到它们时将其删除来加快速度,但如果您想始终保持排序,这可能会成为问题。但是,您最终可以使用它们的 ID 再次对它们进行排序。

      【讨论】:

        猜你喜欢
        • 2017-05-08
        • 2012-11-11
        • 1970-01-01
        • 2020-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多