lambda - java-8 Stream of Map.entry to SortedMap with a custom comparator -
this method takes map values equal null , returns sortedmap of same keys, new values (obtained via objectivefitness)
step 1. first, take keys input map , construct new hashmap same keys, new values 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 have keys. .stream() .collect(collectors.tomap(p -> p, p -> this.objectivefitness(p)));
step 2. next step use stream collect of entries hashmap sortedmap custom comparator.
after reading oracle website: http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
...i found since want maintain sortedness of sortedmap based on other natural ordering of entries, need implement comparator 2 parts. i'll sorting based on fitness value, using key compare uniqueness. *also, want case 2 values can similar, don't want
one part sorting , returns (1,0, or -1) depending on values. other part of comparator has uniqueness (since maps don't allow duplicates. here's best shot far, 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 = 0; < 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 consistent equals? can't tell how implement it.
if correct, want use comparator above me collect treemap using lambdas, i'm getting stuck on , over.
i looked at: java treemap comparator , see comments ordering of sortedmap based on keys because uses navigablemap , therefor sorts on keys, else comparator. there no way without using sortedset?
sortedmap<integer[], integer> sortedfitpop = fitpop.entryset() .stream() //now want insert entries treemap //with sortedness according comparator above .collect(collectors.tocollection((k,v) -> (k,v), new treemap(fitnessorder) ));
the keys should still keys, values should still in hashmap, when collecting, want treemap should sorted beginning , after every entry put.
& yes, of course better not collect hashmap start, , feel there way using java-8/streams/lambdas cleanly.
thank in advance! want know stuff hard!
as already said flown, impossible create treemap
sorted values. think it. how should map implement lookup, when needs result of lookup determine place within map? work if map operations degrade linear searches through whole map or worse.
the other issue has been mentioned yourself: consistency equals
. comparator using value of map can’t consistent equals
of keys, comparator dedicated integer[]
keys can’t consistent equals
java arrays don’t have equals
method. strikes when using, e.g. linkedhashmap
, sort value before insertion. in case, lookup work identical array object instance rather equivalent sequence of elements, arrays have no appropriate hashcode
or equals
implementation.
this point consider shouldn’t use integer[]
arrays anyway. might have been confused fact generics don’t support primitive types, array of primitive type not primitive type. there’s no reason not use int[]
here.
when using int[]
arrays, can use intbuffer
wrap them, getting type implements comparable
, hashcode
, equals
consistently based on int[]
’s contents. then, can create linkedhashmap
sorted stream. reflect encounter order of stream’s elements, desired ordering, long don’t modify map later-on.
// convert int[] arrays intbuffer via intbuffer.wrap first public map<intbuffer, integer> evaluate(map<intbuffer, integer> population, …) { map<intbuffer, integer> fitpop = population.keyset().stream() .map(ia -> new abstractmap.simpleimmutableentry<>(ia, objectivefitness(ia.array()))) .sorted(map.entry.<intbuffer,integer>comparingbyvalue() .thencomparing(map.entry.comparingbykey())) .collect(collectors.tomap(map.entry::getkey, map.entry::getvalue, (a,b)->{ throw new illegalstateexception(); }, linkedhashmap::new)); return fitpop; }
seeing this, might think whether map integer array integer appropriate representation of population. when create dedicated type population member holding identity criteria , current fitness, can rid of these obstacles. simple list or array of these population members sufficient represent population. recalculating fitness simple foreach
operation , sorting list or array according fitness property easy (you don’t need think ordering of elements same fitness then, there’s no problem having elements same fitness in array or list).
Comments
Post a Comment