Search code examples
javadata-structuresdictionarytreemapsortedmap

Converting the sort order of a given SortedMap depending on the key property


I have a SortedMap ( the implementation is a TreeMap ) that looks something like this:

[ProjectOne] -> [ActivityOne,ActivityTwo,ActivityThree]
[ProjectTwo] -> [ActivityFour,ActivityFive,ActivitySix]
[ProjectThree] -> [ActivitySeven,ActivityEight,ActivityNine]
[ProjectFour] -> [ActivityTen,ActivityEleven,ActivityTwelve]

Every Activity has a Project and currently the map is grouped by the Projects of activities. So ActivityOne has ProjectOne, ActivityFour has ProjectTwo etc..

Every Project has a Unit. So classes look like this:

class Project{
    int id;
    Unit unit;
}

and Unit class:

class Unit{
    int id;
}

and Activity class:

class Activity{
    int id;
    Project project;
}

Now assume ProjectOne and ProjectThree has the same Unit ( lets say where id = 1 ), and ProjectTwo and ProjectFour has the same Unit ( where id = 2 ). I need to convert the SortedMap I have into this:

[ProjectOne] -> [ActivityOne,ActivityTwo,ActivityThree]
[ProjectThree] -> [ActivitySeven,ActivityEight,ActivityNine]
[ProjectTwo] -> [ActivityFour,ActivityFive,ActivitySix]
[ProjectFour] -> [ActivityTen,ActivityEleven,ActivityTwelve]

What I mean is, I need sort the given map depending on the Unit of the Project Elements.

So I need a method:

public SortedMap<Project,List<Activity>> sortByUnits(SortedMap<Project,List<Activity>> mapToBeSorted){
    // Implementation here... 
    return newMapThatIsSorted;
}

How can I achieve this?

I have been trying this whole day and I guess I am not able to solve it. Any help is appreciated.


Solution

  • For proper working, Project needs an additional attribute such as id:

    class Project {
        String id;
        Unit unit;
        public Project(final String id) {
            this.id = id;
        }
        @Override
        public String toString() {
            return this.id + ": unit = " + this.unit.id;
        }
    }
    

    Then we are ready to setup the map with a custom Comparator:

    final SortedMap<Project, List<Activity>> map = new TreeMap<>(new Comparator<Project>() {
        @Override
        public int compare(final Project p1, final Project p2) {
            final int c = Integer.valueOf(p1.unit.id).compareTo(Integer.valueOf(p2.unit.id));
            if (c != 0) {
               return c;
            }
            return p1.id.compareTo(p2.id);
        }
    });
    

    If we don't add id to Project and use it in the Comparator, Project instances with the same Unit.id are considered to be equal.