How to index a multimap based on several criteria?

115 views Asked by At

I have a List of "SomeClass" which may consist of a lot of functionally equal objects, and I need to group these. The entries with identical getName(), getInputDate(), getOutputDate() and getValue() should be grouped together. I came across Multimap which seems to be what i need, but I can't figure out an elegant way how to group these.

Currently I have used them all as the key to the Multimap, but I don't think this is the best solution..

private ImmutableListMultimap<String, SomeClass> getGrouped() {
        return Multimaps.index
                (someClassList, new Function<SomeClass, String>() {
                    public String apply(SomeClass someClass) {
                        return someClass.getName() + someClass.getInputDate() + someClass
                                .getOutputDate() + someClass.getValue();
                    }
                });
}
1

There are 1 answers

3
Liviu Stirb On BEST ANSWER

The problem with your code is the key. Collapsing value into a string in order to obtain a key is not a good idea. I would create a key object and use the rest of your code:

public class PersonGroup{
    private String name;
    private Date input;
    private Date output;
    private String value;

    public PersonGroup(String name, Date input, Date output, String value) {
        this.name = name;
        this.input = input;
        this.output = output;
        this.value = value;
    }

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

        PersonGroup that = (PersonGroup) o;

        if (input != null ? !input.equals(that.input) : that.input != null) return false;
        if (name != null ? !name.equals(that.name) : that.name != null) return false;
        if (output != null ? !output.equals(that.output) : that.output != null) return false;
        if (value != null ? !value.equals(that.value) : that.value != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (input != null ? input.hashCode() : 0);
        result = 31 * result + (output != null ? output.hashCode() : 0);
        result = 31 * result + (value != null ? value.hashCode() : 0);
        return result;
    }
}

update your code to something like

private ImmutableListMultimap<PersonGroup, SomeClass> getGrouped() {
        return Multimaps.index
                (someClassList, new Function<SomeClass, PersonGroup>() {
                    public PersonGroup apply(SomeClass someClass) {
                        return new PersonGroup(someClass.getName(), someClass.getInputDate(), someClass
                                .getOutputDate(), someClass.getValue());
                    }
                });
    }