This article covers some of the aspects of sorting Map in Java. Java Map comes in different flavours, like HashMap, TreeMap, LinkedHashMap etc. TreeMap for instance will sort the data based on the keys. We can also pass a custom Comparator to sort based on the keys as per the custom sort algorithm.
Table of Content
How to Sort HashMap in java
This article covers some of the aspects of sorting Map in Java. Java Map comes in different flavours, like HashMap, TreeMap, LinkedHashMap etc. TreeMap for instance will sort the data based on the keys. We can also pass a custom Comparator to sort based on the keys as per the custom sort algorithm.
We can have two requirements in terms of sorting, first one is sorting by Keys and second is Sorting by Values. Following examples demonstrates few approaches for sorting by key and sorting by value. Following examples uses Java Lambda and Stream api to sort Java HashMap instance.
Sort by Value
Map sort by value in revere order
Following code snippet sorts the map based on value in reverse order and populates a new map reverseSortedMap from the data.
//LinkedHashMap preserve the ordering of elements in which they are inserted
Map reverseSortedMap = new LinkedHashMap();
//Use Comparator.reverseOrder() for reverse ordering
map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.forEachOrdered(x -> reverseSortedMap.put(x.getKey(), x.getValue()));
Sort By Key
Map sort by key in revere order
Following code snippet sorts the map based on the keys in reverse order.
//LinkedHashMap preserve the ordering of elements in which they are inserted
Map reverseSortedMapByKey = new LinkedHashMap();;
//Use Comparator.reverseOrder() for reverse ordering
map.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
.forEachOrdered(x -> reverseSortedMapByKey.put(x.getKey(), x.getValue()));
System.out.println("Sorted by Value Map : " + reverseSortedMapByKey);
Full Example
MapSortJava
public class MapSortJava {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(101, "Tokyo");
map.put(3, "New York");
map.put(2, "San Francisco");
map.put(14, "Los Angels");
map.put(5, "Austin");
System.out.println("Unsorted Map : " + map);
// LinkedHashMap preserve the ordering of elements in which they are inserted
Map<Integer, String> reverseSortedMap = new LinkedHashMap<Integer, String>();;
// Use Comparator.reverseOrder() for reverse ordering
map.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.forEachOrdered(x -> reverseSortedMap.put(x.getKey(), x.getValue()));
System.out.println("Sorted by Value Map : " + reverseSortedMap);
// LinkedHashMap preserve the ordering of elements in which they are inserted
Map<Integer, String> reverseSortedMapByKey = new LinkedHashMap<Integer, String>();;
// Use Comparator.reverseOrder() for reverse ordering
map.entrySet().stream().sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
.forEachOrdered(x -> reverseSortedMapByKey.put(x.getKey(), x.getValue()));
System.out.println("Sorted by Value Map : " + reverseSortedMapByKey);
}
}
Output
Unsorted Map :
2 ==> San Francisco
3 ==> New York
101 ==> Tokyo
5 ==> Austin
14 ==> Los Angels
Sorted by Value Map (Reverse) :
2 ==> San Francisco
3 ==> New York
101 ==> Tokyo
5 ==> Austin
14 ==> Los Angels
Sorted by Value Map (Reverse) :
101 ==> Tokyo
14 ==> Los Angels
5 ==> Austin
3 ==> New York
2 ==> San Francisco
Summary of steps
- Get the entry set by calling the Map.entrySet().
- Get the entry set stream by calling stream() method.
- Use the Map.Entry.comparingByValue() or Map.Entry.comparingByKey().
- Call the sorted method with a Comparator.
- call the terminal operation forEachOrdered to store the each entries in the new Map.
Java TreeMap with Custom Comparator
April 28, 2020
Comparator
Map
This article covers some of the aspects of sorting Map in Java. Java Map comes in different flavors, like HashMap, TreeMap, LinkedHashMap etc. TreeMap for instance will sort the data
based on the keys. We can also pass a custom Comparator to sort based on the keys as per the custom sort algorithm.
Table of Content
How to use custom comparator for TreeMap
This article covers some of the aspects of sorting Map in Java. Java Map comes in different flavors, like HashMap, TreeMap, LinkedHashMap etc. TreeMap for instance will sort the data
based on the keys. We can also pass a custom Comparator to sort based on the keys as per the custom sort algorithm.
TreeMap sorts based on natural ordering of the keys if no custom Comparator is provided.
To use a custom Comparator we need to pass the Comparator in the TreeMap Constructor.
Simple TreeMap
TreeMap without any Comparator
Following code creates a TreeMap and adds some data to it. After that we print the TreeMap. As No comparator is specified, the data is sorted by natural ordering of the keys.
TreeMap map = new TreeMap();
map.put(1, "A");
map.put(3, "C");
map.put(2, "B");
map.put(4, "D");
map.put(5, "E");
System.out.println("\nPrint Map ");
map.forEach((a, b) -> {
printKeyVal(a,b);
});;
Print Map
Key: 1 Value: A Key: 2 Value: B Key: 3 Value: C Key: 4 Value: D Key: 5 Value: E
TreeMap with Comparator
TreeMap with reverse order Comparator
In this case we are passing a built in Comparator to sort the keys reversely. From the result we can see that the data is sorted in reverse order of the keys.
System.out.println("\nPrint Map with Reverse Comparator");
TreeMap map2 = new TreeMap(Collections.reverseOrder());
map2.putAll(map);
map2.forEach((a, b) -> {
printKeyVal(a, b);
});
Print Map with Reverse Comparator
Key: 5 Value: E Key: 4 Value: D Key: 3 Value: C Key: 2 Value: B Key: 1 Value: A
Custom Comparator
Following examples shows implementation of two custom Comparator, one with inner class
second one with java 8 Lambda. Both the Comparator works exactly same, that is it sorts the data in reverse order.
With Inner Classes
Custom Comparator with Inner Class to sort the keys in reverse order.
Comparator orderByKeyDesc = new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
};
Lambda Comparator.
Java 8 Lambda to implement Comparator
Comparator orderByKeyDesc2 = (Integer o1, Integer o2) -> o2.compareTo(o1);
Full Example
TreeMapCustomComparator
Full example with Custom Comparator that is passed to the TreeMap.
public class TreeMapCustomComparator {
public static void main(String[] args) {
TreeMap map = new TreeMap();
map.put(1, "A");
map.put(3, "C");
map.put(2, "B");
map.put(4, "D");
map.put(5, "E");
System.out.println("\nPrint Map ");
map.forEach((a, b) -> {
printKeyVal(a, b);
});;
System.out.println("\nPrint Map with Reverse Comparator");
TreeMap map2 = new TreeMap(Collections.reverseOrder());
map2.putAll(map);
map2.forEach((a, b) -> {
printKeyVal(a, b);
});
//Custom Comparator with Inner Class
Comparator orderByKeyDesc = new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
};
//Custom Comparator with Lambda
Comparator orderByKeyDesc2 = (Integer o1, Integer o2) -> o2.compareTo(o1);
System.out.println("\nPrint Map with Custom Reverse Comparator Java Lambda");
TreeMap map3 = new TreeMap(orderByKeyDesc2);
map3.putAll(map);
map3.forEach((a, b) -> {
printKeyVal(a, b);
});
}
/* Utility method to print key value pairs nicely */
private static void printKeyVal(Object a, Object b) {
System.out.print("Key: " + a + " Value: " + b + " ");
}
}
Print Map
Key: 1 Value: A Key: 2 Value: B Key: 3 Value: C Key: 4 Value: D Key: 5 Value: E
Print Map with Reverse Comparator
Key: 5 Value: E Key: 4 Value: D Key: 3 Value: C Key: 2 Value: B Key: 1 Value: A
Print Map with Custom Reverse Comparator Java Lambda
Key: 5 Value: E Key: 4 Value: D Key: 3 Value: C Key: 2 Value: B Key: 1 Value: A
How to convert ByteBuffer to String
April 23, 2020
ByteBuffer Class is part of Java NIO. It extends java.nio.Buffer and used to handle data read and write to NIO Channels. This article demonstrates few ways to handle conversion between ByteBuffer to String and converting String to ByteBuffer object.
Convert ByteBuffer to String and viceversa
ByteBuffer Class is part of Java NIO. It extends java.nio.Buffer and used to handle data read and write to NIO Channels. This article demonstrates few ways to handle conversion between ByteBuffer to String and converting String to ByteBuffer object.
Convert String to ByteBuffer
Following code converts the String data to ByteBuffer object using Charset.forName. We need to specify the appropriate character set .
String data = "this is my string";
ByteBuffer buff = Charset.forName("UTF-8").encode(data);
Convert ByteBuffer to String
Following code sample shows two methods, both can be used to convert ByteBuffer object back to a String. We need to specify the same character set, that was used to encode, otherwise we might get a different String.
public static String getData (ByteBuffer buff) {
return new String(buff.array(), StandardCharsets.UTF_8 );
}
public static String getData2 (ByteBuffer buff) {
return StandardCharsets.UTF_8.decode(buff).toString();
}
Writing and reading File using FileChannel
April 21, 2020
FileChannel
NIO
FileChannel is available as a part of Java NIO (New IO). Java NIO (New IO) is an alternative to the standard Java IO API's. Java NIO offers a different way of working with IO than the standard IO API's. File channels are safe for use by multiple concurrent threads. This article demonstrate with working example of how to write and read file using FileChannel.
Table of Content
Java File Channel
FileChannel is available as a part of Java NIO (New IO).Java NIO (New IO) is an alternative to the standard Java IO API's. Java NIO offers a different way of working with IO than the standard IO API's. File channels are safe for use by multiple concurrent threads. This article demonstrate with working example of how to write and read file using FileChannel.
Advantages of File Channels
- File channels are safe for use by multiple concurrent threads.
- Reading and writing at a specific position in a file.
- transfer file data from one channel to another at a faster rate.
- lock a section of a file to restrict access by other threads.
Example of Reading and Writing File
Following example demonstrate how to read and write file using FileChannel.
JavaFileChannelHelper
package bootng.com.files;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
public class JavaFileChannelHelper {
public static void main(String[] args) {
JavaFileChannelHelper example = new JavaFileChannelHelper();
try {
example.write("samplefile.txt","This is it");
String content = example.read("samplefile.txt");
System.out.println(content + " " );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String read(String source) throws IOException {
StringBuilder content = new StringBuilder("");
RandomAccessFile file = new RandomAccessFile(source, "r");
FileChannel channel = file.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
while (channel.read(buf) > 0) {
content.append(new String(buf.array(), StandardCharsets.UTF_8 ));
}
System.out.println("Read success!");
return content.toString();
}
public void write(String source, String content) throws IOException {
RandomAccessFile file = new RandomAccessFile(source, "rw");
FileChannel channel = file.getChannel();
ByteBuffer buff = ByteBuffer.wrap(content.getBytes(StandardCharsets.UTF_8));
channel.write(buff);
System.out.println("Write success!");
}
}
Notes
- Channels read and write buffers containing the content.
- Channels are bi directional, that is we can both write and read in a channel.
How to list all files in a directory in java
April 18, 2020
Java
Table of Content
How to list all files in a directory in java
Say we want get names of all the files under a directory and sub directories. Basically we need to able to look under each sub directory and if it has any files add to the result. This sounds like a problem that can be solved recursively.
In the following section we have two different methods doing the same thing. Example 1 we are creating a File object with given path and iterating over its contents. And if the content is file we are adding it to return list.
List the file names by calling listFiles on the root path, and then recursively calling it if we get any directory.