This method takes a Map with all values equal to null and returns a SortedMap of the same keys, with new values (obtained via objectiveFitness)
Step 1. First, I take the keys from the input Map and construct a new HashMap with the same keys, new values are objectiveFitness(key).
public SortedMap<Integer[], Integer> evaluate(Map<Integer[], Integer> population, Integer[] melody, Integer[] mode) {
Map<Integer[], Integer> fitPop = new HashMap<>();
fitPop = population.keySet() //you just have the keys.
.stream()
.collect(Collectors.toMap(p -> p, p -> this.objectiveFitness(p)));
Step 2. The next step is to use a Stream to collect all of the entries from the HashMap into a SortedMap with a custom Comparator.
After reading this from the Oracle website: http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
...I found since I want to maintain sortedness of the SortedMap based on something other than the natural ordering of the entries, i need to implement a Comparator with 2 parts. I'll be sorting based on fitness value, using the key to compare for uniqueness. *Also, I want the case for where 2 values can be similar, but I don't want to
One part is to do with sorting and returns (1,0, or -1) depending on the values. The other part of the Comparator has to do with uniqueness (since Maps don't allow duplicates. Here's my best shot so far, but I'm struggling.
Comparator<Map.Entry<Integer[], Integer>> fitnessOrder =
new Comparator<Map.Entry<Integer[], Integer>>() {
public int compare(Map.Entry<Integer[], Integer> m1, Map.Entry<Integer[], Integer> m2) {
int fitCmp = m2.getValue().compareTo(m1.getValue());
if (fitCmp != 0)
return fitCmp;
if(m1.getKey().equals(m2.getKey())) return 0;
for(int i = 0; i < m1.getKey().length; i++){
if(m1.getKey()[i] > m2.getKey()[i]){
return 1;
}
if(m1.getKey()[i] < m2.getKey()[i]){
return -1;
}
}
return 0;
}
};
Does that look like it is consistent with equals? I can't really tell how to implement it.
If it is correct, I want to use the Comparator above to help me collect into a TreeMap using lambdas, however I'm just getting stuck over and over.
I also looked at: Java TreeMap Comparator and I see the comments about ordering of a SortedMap based on the keys because it uses a NavigableMap and therefor sorts on keys, else by a comparator. Is there really no good way to do this without using a SortedSet?
SortedMap<Integer[], Integer> sortedFitPop = fitPop.entrySet()
.stream()
//now I want to insert entries into the TreeMap
//with sortedness according to the Comparator above
.collect(Collectors.toCollection((k,v) -> (k,v), new TreeMap(fitnessOrder)
));
the keys should still be the keys, the values should still be what they were in the HashMap, but now when collecting, I want the TreeMap should always be sorted from the beginning and after every entry is put.
& yes, of course it would be even better not to collect into a HashMap to start, and I feel like there is a way to do so using Java-8/streams/lambdas to do it cleanly.
Thank you in advance! I want to know this stuff so hard!