Sorting a hashmap in reverse order using Double - java

I know there are a number of posts that describe how to sort a hashmap in reverse. I've tried them and I've struggled to make it work. I'm relatively new to Java.
Below, I can print the hashmap in order from lowest double to highest double, but how do I sort it so the highest double comes first?
I've followed this post unsuccessfully.
I want to sort the following in reverse order the hashMap called "lines":
public void sortResults(HashMap<Double, TextObject> lines) {
Map<Double,TextObject> sortedMap = new TreeMap<Double,TextObject>(lines);
System.out.println("**************************************");
for (Map.Entry<Double, TextObject> entry : sortedMap.entrySet()) {
System.out.println("Key : " + entry.getKey()
+ " Value : " + entry.getValue());
}
System.out.println();
}

You can create TreeMap with reverse comparator and then use putAll to add lines
Map<Double,TextObject> sortedMap = new TreeMap<Double,TextObject>(Comparator.reverseOrder());
sortedMap.putAll(lines);

Related

Get first k values from HashMap

I am trying to get first k values from a hashmap.
I know how to get all values from a hashmap and also how to iterate over all of them. Is there any short way to generate first k values from hashmap
for (Map.Entry<String, Integer> en : hmap.entrySet())
{
System.out.println("Key = " + en.getKey() + ", Value = " + en.getValue());
}
The notion of the first elements is undefined for Map interface. How it was mentioned in comments you can use LinkedHashMap or TreeMap where the first item make sense.
If you just want to get some limit number of map values, you could use stream api with limit:
hmap.entrySet().stream()
.limit(2)
.collect(Collectors.toList());

Java Printing all of my maps keys and values

Quick question and its probably the most simple answer but i need to print a textual representation of my HashMaps contents.
My code so far is:
public void printAll() {
Set< String> Names = customersDetails.keySet();
Collection< CustomerDetails> eachCustomersNames = customersDetails.values();
for (String eachName : Names) {
System.out.println(eachName)
}
for (CustomerDetails eachCustomer : eachCustomersNames) {
System.out.println(eachCustomer);
}
}
But this results in the list of keys and then a list of values but i need each line of text to read something like
Bob [example]
Where Bob is the key and example is the value.
If you're using Java 8, you can take advantage of lambda syntax and .forEach() like so:
customersDetails.forEach((k,v) -> {
System.out.println(k + "[" + v + "]");
});
Where k is your key and v is the value tied to key k.
Every key maps to just one value, so you can just do this:
Set < String> Names = customersDetails.keySet();
for (String eachName: Names) {
System.out.println(eachName + " [" + customersDetails.get(eachName).toString() + "]")
}
If you're not using Java 8, simply print both key and value for each key:
for (String eachName : Names) {
System.out.println(eachName + " [" + customersDetails.get(eachName) + "]");
}
You can print your Map like so :
Map<String, String> customersDetails = new HashMap<>();
for (Map.Entry<String, String> entry : customersDetails.entrySet()) {
System.out.println(entry.getKey() + '[' + entry.getValue() + ']');
}
If you are using java 8 you can use :
customersDetails.entrySet().forEach((entry) -> {
System.out.println(entry.getKey() + '[' + entry.getValue() + ']');
});
If you start dealing with maps with more complicated types consider using ReflectionToStringBuilder. Internally it uses reflection to build a string of an object and its fieldd. It recurses through the object graph too.
It may not be efficient, but it helps a lot with debugging and printing operations.
You don't need to iterate over your keys/values in order to print your map, as the HashMap.toString() method already does this for you very efficiently (actually, it's the AbstractMap.toString() method).
If you have your CustomerDetails class implement the toString() method, then you only need to do:
System.out.println(customerDetails);
And this will print your map in the format you require.

Scroll LinkedHashMap to key

How do I scroll a LinkedHashMap to a specific key? Something like this:
LinkedHashMap<String,String> queque = new LinkedHashMap<String,String>();
queque.put("uno","uno");
queque.put("due","due");
queque.put("tre","tre");
queque.put("quattro","quattro");
queque.put("cinque","cinque");
Iterator i = queque.entrySet().iterator();
while(i.next().getKey().equals(quattro)) {
System.out.print(i.getKey() + ": ");
System.out.println(i.getValue());
i.next();
}
You don't have to explicitly iterate (unless you really want to) to get the value by key: just use get() method:
System.out.println("quattro" + ": " + queque.get("quattro"));
If you want to print all the values up to the certain one, you can do the following:
Iterator i = queque.entrySet().iterator();
while(i.hasNext()) {
Map.Entry<String, String> me = i.next();
if (me.getKey() == "quattro") break;
System.out.println(me.getKey() + ": " + me.getValue());
}
Or, a little more elegant:
for (Map.Entry<String, String> me : queque.entrySet()) {
if (me.getKey() == "quattro") break;
System.out.println(me.getKey() + ": " + me.getValue());
}
Couple more points:
If you do not need to store the elements in the order they were added, use HashMap rather than LinkedHashMap, since former is faster. If you want store elements sorted, use TreeMap(but beware it is slower than the other types of Map).
When you create instance of container in Java, you are better off using interface (like Map, List or Set) in the left part of assignment and implementation (like HashMap, ArrayList etc.) in the right part since it gives you much more flexibility: in case you later on decide to change the implementation of the same interface (e.g. use HashMap instead of LinkedHashMap as I suggested above), you only need to change one line of your code where you create this container, rather than change all places where this container is used.
If you want to do it right with Iterator you would do
Iterator<Entry<String, String>> i = queque.entrySet().iterator();
while (i.hasNext()) {
Entry<String, String> entry = i.next();
if ("quattro".equals(entry.getKey()))
break;
System.out.println(entry.getKey() + ": " + entry.getValue());
}
But that is equivalent to using an enhanced for loop like so:
for (Entry<String, String> entry : queque.entrySet()) {
if ("quattro".equals(entry.getKey()))
break;
System.out.println(entry.getKey() + ": " + entry.getValue());
}
with Iterator you'll have to check hasNext(), only then call next() once(!) per loop or your iterator would advance by two elements. You should also never compare Strings with ==, that's just not working.
Sounds like you should be using TreeMap to me. Then you just use TreeMap.headMap().

ClassCastException: java.util.ArrayList is not Comparable

I have two arrays in my Hash map and I want to sort the values stored in the averageValueArray according to the time in the timeStampArray. I am using TreeMap but I am getting ClassCastException which says that ArrayList is not comparable.
This is what I am doing:
Map<List<Date>,List<Double>> sortMap = new HashMap<List<Date>,List<Double>>();
sortMap.put(timeStampArray, averageValueArray);
for (Map.Entry entry : sortMap.entrySet()) {
System.out.println("Key = " + entry.getKey());
System.out.println(" Value = " +entry.getValue());
}
System.out.println("Unsort Map......");
printMap(sortMap);
System.out.println("Sorted Map......");
TreeMap<List<Date>,List<Double>> treeMap = new TreeMap<List<Date>,List<Double>>(sortMap);
for (Map.Entry entry : treeMap.entrySet()) {
System.out.println("Key = " + entry.getKey());
System.out.println(" Value = " +entry.getValue());
}
printMap(treeMap);
And the printMap is:
public static void printMap(Map<List<Date>,List<Double>> map) {
for (Map.Entry entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() + " Value : "
+ entry.getValue());}}
As the error message says, ArrayList does not implement the Comparable interface that is required by TreeMap to do the ordering of the elements in the map. You can, however, create the TreeMap with the constructor that takes a Comparator instead, and implement the comparator according to your ordering rules.
From Java doc of TreeMap
A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
List does not implements Comparable so you need to provide Comparator
I still can't figure out why are you using List. What you need can just be possible using TreeMap<Date, Double>
You need to use a comparator as the key of your tree map doesn't implement the Comparable interface.
There's a TreeMap constructor which accepts a custom Comparator and you can implement that with your custom logic.

Java - Iterating over a Map which contains a List

First time here so I hope this makes sense!
I have a Map which contains a String as it's Key, and a List of Strings as it's Value. I need to iterate over all vlaues contained within each List within the Map.
So, first I want to get the Keys, which works:
Set<String> keys = theMap.keySet();
This returns me a Set containing all my Keys. Great :)
This is where I've got stuck - most of the info on the web seems to assume that the values I'd want returned from the Key would be a simple String or Integer, not another Set, or in this case a List. I tried theMap.values() but that didn't work, and I tried a forloop / for:eachloop, and neither of those did the trick.
Thanks y'all!
for(List<String> valueList : map.values()) {
for(String value : valueList) {
...
}
}
That's really the "normal" way to do it. Or, if you need the key as well...
for(Map.Entry<String, List<String>> entry : map.entrySet()) {
String key = entry.getKey();
for (String value : entry.getValue()) {
...
}
}
That said, if you have the option, you might be interested in Guava's ListMultimap, which is a lot like a Map<K, List<V>>, but has a lot more features -- including a Collection<V> values() that acts exactly like what you're asking for, "flattening" all the values in the multimap into one collection. (Disclosure: I contribute to Guava.)
I recommend iterating over Map.entrySet() as it is faster (you have both, the key and the value, found in one step).
Map<String, List<String>> m = Collections.singletonMap(
"list1", Arrays.asList("s1", "s2", "s3"));
for (Map.Entry<String, List<String>> me : m.entrySet()) {
String key = me.getKey();
List<String> valueList = me.getValue();
System.out.println("Key: " + key);
System.out.print("Values: ");
for (String s : valueList) {
System.out.print(s + " ");
}
}
Or the same using the Java 8 API (Lambda functions):
m.entrySet().forEach(me -> {
System.out.println("Key: " + me.getKey());
System.out.print("Values: ");
me.getValue().forEach(s -> System.out.print(s + " "));
});
Or with a little bit of Java Stream API mapping hardcore and method reference :-)
m.entrySet().stream().map(me -> {
return "Key: " + me.getKey() + "\n"
+ "Values: " + me.getValue().stream()
.collect(Collectors.joining(" "));
})
.forEach(System.out::print);
And the output is, as expected:
Key: list1
Values: s1 s2 s3
You need a Map<String, List<String>>
The left hand side String is the key, the right hand side List<String> is the value, which in this case is a List of Strings
Another example with the Java 8 API (lambda function).
When you want to iterate over:
Map<String, List<String>> theMap = new HashMap<>();
theMap.forEach((key, value) -> {
System.out.println("KEY: " + key);
System.out.print("VALUES: ");
value.forEach(System.out::println);
});

Categories

Resources