Search code examples
javafunctional-programmingvavr

Grouping strings together in Vavr


I'm trying this code below:

final Map<Word, List<Word>> tuple2s = lowercase
            .groupBy(identity());

but this creates groups of single strings, basically like doing a #split:

LinkedHashMap((lorem, List(lorem)), (ipsum, List(ipsum)), (lorem, List(lorem)), (lorem, List(lorem)), (ipsum, List(ipsum)), (dolor, List(dolor)), (sit, List(sit)), (dolor, List(dolor)), (sit, List(sit)), (dolor, List(dolor)), (elit, List(elit)))

How do I fix this? The expected value is

LinkedHashMap((lorem, List(lorem, lorem, lorem)), (ipsum, List(ipsum, ipsum)), (dolor, List(dolor, dolor, dolor)), (sit, List(sit, sit)), (elit, List(elit)))

Solution

  • You need a correct implementation of equals and hashCode in your Word class, that is based on the string content of the word that it represents. With that in place, List.groupBy(...) will result in what you would expect. Something similar to the following will suffice.

    public class Word {
        private String word;
    
        public Word(String word) { this.word = word; }
    
        @Override
        public String toString() { return word; }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Word other = (Word) o;
            return Objects.equals(word, other.word);
        }
    
        @Override
        public int hashCode() { return Objects.hash(word); }
    }