0

I have hashmap as

Map<Integer, CustomClass> 

CustomClass is defined as


Class CustomClass {
    String s,
    Integer i
... constructors & getter setters
}

I have the object initialization as

Map<Integer, CustomClass> map = new HashMap<>() 

populated with the values.

I want to sort on the basis of the CustomClass's String s data member.

I have tried writing lambda expression but unable to get the proper sorted order map.

I have tried mocking the following code

import java.util.*;
    
    class FileMap implements Comparable<FileMap>{
      private String fileName;
      private int file;
      public FileMap(String fileName, int file){
        this.fileName = fileName;
        this.file = file;
      }
    
      public String getFileName() {
        return fileName;
      }
    
      public void setFileName(String fileName) {
        this.fileName = fileName;
      }
    
      public int getFile() {
        return file;
      }
    
      public void setFile(int file) {
        this.file = file;
      }
        @Override
        public int compareTo(FileMap that){
            return this.fileName.compareTo(that.getFileName());
        }
        @Override
        public String toString(){
            return this.fileName;
        }
    }
    class Main {
      public static void main(String[] args) {
        FileMap fm1 = new FileMap("abc.txt", 0);
        FileMap fm2 = new FileMap("abd.txt", 0);
        FileMap fm3 = new FileMap("abe.txt", 0);
        FileMap fm4 = new FileMap("abf.txt", 0);
        Map<Integer, FileMap> fileMap = new HashMap<>();
          fileMap.put(0, fm1);
          fileMap.put(1, fm3);
          fileMap.put(2, fm2);
          fileMap.put(3, fm4);
        System.out.println(fileMap); 
    
        Map<Integer, FileMap> tree = new TreeMap<>();
          tree.putAll(fileMap);
          System.out.println(tree);
      }
    }

  • I have edited the post and added the mock implementation @AlexanderIvanchenko – Bhupesh Patil Oct 30 '22 at 14:29
  • You forget to clarify what's wrong with the code you've posted (show the output you have, and the output you need). – Alexander Ivanchenko Oct 30 '22 at 14:33
  • Your test (unfortunately) has same order (0..3;ab..Bf)...but Tree(sorted) map (at all) sorts by a *key* (+/-comparator). ..if you want to sort the *values*: "double map"!;) – xerx593 Oct 30 '22 at 14:53

1 Answers1

0

TreeMap maintains the order of entries based on its Keys, not on its Values. Therefore, you can't instruct it to store the entries in the way you need.

As a workaround, you can use a LinkedHashMap which maintains the order of entries were added into the map.

Note that if you update the map afterwards, the order might be disrupted.

That's how it can be implemented using Stream API and Collector to toMap()

Map<Integer, FileMap> fileMap = Map.of(
    0, new FileMap("abc.txt", 0),
    1, new FileMap("abd.txt", 0),
    2, new FileMap("abe.txt", 0),
    3, new FileMap("abf.txt", 0)
);
    
Map<Integer, FileMap> result = fileMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue())
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (left, right) -> { 
            throw new AssertionError("All Keys in the source are expected to be unique");
        },
        LinkedHashMap::new
    ));

The same can be accomplished using plain old imperative programming:

Map<Integer, FileMap> fileMap = Map.of(
    0, new FileMap("abc.txt", 0),
    1, new FileMap("abd.txt", 0),
    2, new FileMap("abe.txt", 0),
    3, new FileMap("abf.txt", 0)
);
    
List<Map.Entry<Integer, FileMap>> sortedEntries = new ArrayList<>(fileMap.entrySet());
sortedEntries.sort(Map.Entry.comparingByValue());
        
Map<Integer, FileMap> result = new LinkedHashMap<>();
        
for (Map.Entry<Integer, FileMap> entry : sortedEntries) {
    result.put(entry.getKey(), entry.getValue());
}
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46