简体   繁体   中英

Sort Double Double HashMap Java/Processing

I have this Hashmap of floats and I want to get the top 5 largest values from it:

import java.util.Map;


HashMap<Float,Float> hm = new HashMap<Float,Float>();

// Putting key-value pairs in the HashMap
for (int i = 0; i < 100; i++) {

  float pos = random(-50, 50);
  float time = random(0, 50);
hm.put(time, pos);

}
// Using an enhanced loop to interate over each entry
for (Map.Entry me : hm.entrySet()) {
  print("key is " + me.getKey());
  println(" value is " + me.getValue());
}

I assume I would need to sort it first. Question is, how to sort it and will the keys still remain the same after the sort? When I say "same" I mean will the sorted values still have the original key identifier? This is crucial for what I am trying to accomplish.

If it is possible, replace HashMap by an implementation of NavigableMap , such as TreeMap . The iteration order of a HashMap is undefined.

With a NavigableMap you can sort it from higher to lower values by means of;

for (Map.Entry me : tm.descendingMap().entrySet() ()) {
  System.out.print("key is " + me.getKey());
  System.out.println(" value is " + me.getValue());
}

It is worth noting that descendingMap() does not actually sort the contents of the map (because the TreeMap is already sorted), but just return a reverse view of the original map.

This code does what you do. I developed and tested it in Processing IDE.

import java.util.Comparator;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.List;

class FloatEntryComparator implements Comparator<Map.Entry> {
  public int compare(Map.Entry e1, Map.Entry e2) {
    return ((Float)e2.getValue()).intValue() - ((Float)e1.getValue()).intValue();
  }
}

void setup() {
  Map<Float,Float> hm = new HashMap<Float,Float>();

  // Putting key-value pairs in the HashMap
  for (int i = 0; i < 100; i++) {
    float pos = random(-50, 50);
    float time = random(0, 50);
    hm.put(time, pos);
  }

  println("ALL ENTRIES, UNSORTED:");  
  for (Map.Entry me : hm.entrySet()) {
    print("key is " + me.getKey());
    println(" value is " + me.getValue());
  }

  List<Map.Entry> entries = new ArrayList<Map.Entry>(hm.entrySet());

  java.util.Collections.sort(entries, new FloatEntryComparator());

  hm = new LinkedHashMap<Float, Float>();
  for(Map.Entry e : entries)
    hm.put((Float)e.getKey(), (Float)e.getValue());

  println("5 LARGEST ENTRIES:");  
  int shownCount = 0;
  for (Map.Entry me : hm.entrySet()) {
    if(shownCount == 5)
      break;
    print("key is " + me.getKey());
    println(" value is " + me.getValue());
    ++shownCount;
  }
}

Explanation:

class FloatEntryComparator implements Comparator<Map.Entry> { ... }

~ here we declare so-called comparator, a class used for sorting a list in a specific order.

void setup() { ... }

~ if I understand it right, this is one of entry points for Processing script. Since we are not drawing anything, we don't implement draw function (yet), only setup.

Map<Float,Float> hm = new HashMap<Float,Float>();
for(...) ...

~ this is initialization part, same as in your code.

List<Map.Entry> entries = new ArrayList<Map.Entry>(hm.entrySet());

~ here hashmap is converted to a list of entries

java.util.Collections.sort(entries, new FloatEntryComparator());

~ here list of entries is sorted by values in descending order

hm = new LinkedHashMap<Float, Float>();
for(Map.Entry e : entries)
  hm.put((Float)e.getKey(), (Float)e.getValue());

~ here list of entries is converted to hashmap. The resulting hashmap is sorted by values in descending order.

Here is the complete Processing script, tested against Processing 2.1:

https://gist.github.com/akhikhl/8258430

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM