Home > Blockchain >  Java group by custom variable and return same object
Java group by custom variable and return same object

Time:03-22

I want to count number of duplicate in my list by custom variable (myHash)

Map<PersonHash, Long> result = list.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

This will count duplicate by id which is value in hash and equals function. How I can count it by custom variable ? In my case it is byte[] myHash

my pojo:

public class PersonHash implements Serializable {
    
    private Long id;
    private byte[] myHash;    
    ....
}

CodePudding user response:

You have to override the equals and hashCode function of your object. Then you can do this with Function.identity(). I have overrides those functions like below:

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    PersonHash personHash = (PersonHash) o;
    return hashCompare(personHash) == 0;
}

@Override
public int hashCode() {
    return myHash.length;
}

public int hashCompare(PersonHash other) {
    int i = this.myHash.length - other.myHash.length;
    if (i != 0) {
        return i;
    }
    for (int j = 0; j < this.myHash.length; j  ) {
        i = this.myHash[j] - other.myHash[j];
        if (i != 0) {
            return i;
        }
    }
    return 0;
}

And now with the following code:

    PersonHash personHash1 = new PersonHash();
    personHash1.setId(1L);
    personHash1.setMyHash(new byte[]{1, 2, 3});
    PersonHash personHash1_2 = new PersonHash();
    personHash1_2.setId(3L);
    personHash1_2.setMyHash(new byte[]{1, 2, 3});
    PersonHash personHash2 = new PersonHash();
    personHash2.setId(2L);
    personHash2.setMyHash(new byte[]{4, 5, 6});
    List<PersonHash> list = new LinkedList<>();
    list.add(personHash1);
    list.add(personHash1_2);
    list.add(personHash2);

    Map<PersonHash, Long> result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

    result.forEach((k, v) -> System.out.println(Arrays.toString(k.getMyHash())   " "   v));

You will get the following output:

[4, 5, 6] 1
[1, 2, 3] 2

PS: Please write better hashCode() function, I just want to demonstrate.

CodePudding user response:

You can't group by myHash and get an instance of PersonHash as key, if myHash is not the identifier and part of equals and hashCode.

If myHash is not part of equals and hashCode, add a getter for myHash

PersonHash {
   getMyHash() {...}
}

and use

Map<byte[], Long> result = list.stream()
        .collect(Collectors.groupingBy(PersonHash::getMyHash, Collectors.counting()));

Afterwards you can match the list with the results to find the objects with the given hash.

Or use

Map<byte[], List<PersonHash>> result = list.stream()
        .collect(Collectors.groupingBy(PersonHash::getMyHash));

to get the list of PersonHash with the same myHash value.

  • Related