0

Lets say we have a class called Activity:

public class Activity { private Project project; } 

So every Activity Object will have a Project.. Also every Project has a Unit. Two different Projects can have the same unit:

public class Project { private String projectName; private Unit unit; } 

And a Unit has a name as well:

public class Unit { private String unitName; } 

So currently I have a TreeMap like this:

SortedMap<Project,List<Activity> myMap 

One example may be:

projectOne -> [activityOne,activityTwo,activityThree] projectTwo -> [activityThree,activityFouractivityFive] projectThree -> [activityFour,activityFive,activitySix] 

etc...

Now lets assume projectOne has the same unit with projectThree (unitAAA) and projectTwo has unitZZZ...

I want to sort my Map alphabetically by the unit of the project elements:

projectOne -> [...] projectThree -> [...] projectTwo -> [...] 

How can I achieve this? I know in Stackoverflow the question is What have you tried so far?, well I am really stuck in this point so I have not really tried anything besides trying to come up with what I can even try..

2 Answers 2

4

A map is basically an unsorted collection but there are sorted maps as well, e.g. TreeMap. In that case provide a comparator which sorts projects based on their to the constructor:

SortedMap<Project, List<Activity>> myMap = new TreeMap<>( new Comparator<Project>() { public int compare( Project lhs, Project rhs) { int r = lhs.unit.unitName.compareTo(rhs.unit.unitName); //note that null checks etc. are omitted for simplicity, don't forget them in your code unless you know for sure that unit and unitName can't be null if( r == 0 && !lhs.equals(rhs)) { //take other properties into account for consistent behavior with equals() //see "Update 2" below } return r; } }); 

Note that if you need to sort the map using a different comparator (or can't provide a comparator) you'd have to create a list using the entries of the map and sort that.

Something like this:

 List<Map.Entry<Project, List<Activity>> l = new ArrayList<>(myMap.entrySet()); Collections.sort(l, new Comparator<Map.Entry<Project, List<Activity>>() { public int compare( Map.Entry<Project, List<Activity> lhs, Map.Entry<Project, List<Activity> rhs) { return lhs.getKey().unit.unitName.compareTo(rhs.getKey().unit.unitName); } }); 

Also note that it is not possible for a collection or sorted map to have different sort orders, i.e. you can only provide one comparator or natural ordering for the elements.

In any case you'd either have to change the sort order of the collection (e.g. by using Collections.sort(...) or, if you need to maintain multiple orders simultanously, use multiple collections (which can be sorted views to a base collection/map).

Update I'll add an example for a copy of the TreeMap:

//new TreeMap like above SortedMap<Project, List<Activity>> copy = new TreeMap<>( new Comparator<Project>() { ... } ); copy.putAll( myMap ); 

Update 2

As for the comparator, note that it is required to be consistent with equals, i.e. the comparator must only return 0 if both objects are equal. Thus you'd need to take other properties of a Project into account if the units are equal. Without that, if two projects use the same unit, they are considered equal by the TreeMap and thus entries might get lost.

For more information see: What does comparison being consistent with equals mean ? What can possibly happen if my class doesn't follow this principle?

The compare method might look like this, if the project names are unique:

public int compare( Project lhs, Project rhs) { //as above null checks etc. are omitted for simplicity's sake int r = lhs.unit.unitName.compareTo(rhs.unit.unitName); if( r == 0 && !lhs.equals(rhs)) { r = lhs.projectName.compareTo( rhs.projectName ); //you could also use the natural ordering of the projects here: //r = lhs.compareTo( rhs ); } return r; } 
Sign up to request clarification or add additional context in comments.

11 Comments

Yes, sorry it is already a TreeMap. But how can I do the conversion?
@KorayTugay by properly implementing compareTo in the Class Project of passing a Comparator at creation time of the TreeMap.
@A4L The tree map is returned from a method that is used in many other places. I can not pass a Comparator to it. I only have the data structure and I must do the modification myself.
@KorayTugay So you need go with nr. 1, i.e. Implement compareTo in which case whoever puts an object of Project it gets sorted the way you want. If you dont want this to happen or cannot do it bacause you can change any of the classes then you might consider copying into a new TreeMap where you can pass a Comparator
@KorayTugay, then add the comparison logic in your Project class by making it implement Comparable and override 'compareTo(Project o)' in it.
|
1

A HashMap can't be sorted, but if you want to display the contents of the map sorted, you could sort a list of your projects by unit (look for a Comparator on Project) and get the value of the corresponding project from the map.

1 Comment

Sorry it is a SortedMap.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.