Get all duplicate objects from list

theokevin :

I want to create a new list with only the transactions from the input list that meet the following requirement: The name and code should be on the input list multiple times. (See example.) The items and ID are not relevant.

Input list

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   |
+----+------+----+-------+

Expected result

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

I've tried using this code

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 );
    }
}

But it seems like this code won't work since the if condition will always be true when it found itself in the list

Is there any way to achieve it without using .stream if possible? Someone said that I can achieve it using map but I can't find the way to do so. It's fine using anything if there is no other option.

I'd have to keep the for loop for my other if() function.

lczapski :

First you can create list of pair (name, code as list) that occurs more than one. Then use this list to filter.

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());

UPDATE

If you want something without stream:

For creating list of duplicates, You can 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()));
    }
}

Then filtering can be done:

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=206281&siteId=1