코딩테스트

Sort a HashMap in Java - (4) Using the Stream API

728x90

Using Lambdas and Streams

Java 8 부터, map을 정렬하기 위해 Stream API 와 Lambda 표현식을 사용할 수 있다.

map의 stream pipeline 에서 sorted 메서드만 호출하면 된다.

 


1. Key로 정렬

Key 값으로 정렬하기 위해 comparingByKey comparator 를 사용해야 한다.

map.entrySet()
  .stream()
  .sorted(Map.Entry.<String, Employee>comparingByKey())
  .forEach(System.out::println);

적용

public class UsingStreamAPI {
	public static void main(String[] args) {
		Map<String, Employee> map = new HashMap<>();

		Employee employee1 = new Employee(1L, "Mher");
		map.put(employee1.getName(), employee1);
		Employee employee2 = new Employee(22L, "Annie");
		map.put(employee2.getName(), employee2);
		Employee employee3 = new Employee(8L, "John");
		map.put(employee3.getName(), employee3);
		Employee employee4 = new Employee(2L, "George");
		map.put(employee4.getName(), employee4);
		
		map.entrySet()
		  .stream()
		  .sorted(Map.Entry.<String, Employee>comparingByKey())
		  .forEach(System.out::println);
		
	}
}

결과

마지막 forEach 단계에서 결과를 출력해보자.

데이터는 기본적으로 오름차순 정렬된다.

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

 

2. Value로 정렬

Employee 객체도 정렬이 가능하다.

map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .forEach(System.out::println);

적용

public class UsingStreamAPI {
	public static void main(String[] args) {
		Map<String, Employee> map = new HashMap<>();

		Employee employee1 = new Employee(1L, "Mher");
		map.put(employee1.getName(), employee1);
		Employee employee2 = new Employee(22L, "Annie");
		map.put(employee2.getName(), employee2);
		Employee employee3 = new Employee(8L, "John");
		map.put(employee3.getName(), employee3);
		Employee employee4 = new Employee(2L, "George");
		map.put(employee4.getName(), employee4);
		
		map.entrySet()
		  .stream()
		  .sorted(Map.Entry.comparingByValue())
		  .forEach(System.out::println);
		
	}
}

결과

id 값을 기준으로 Employee 객체가 정렬된 모습을 볼 수 있다.

Mher=Employee {id=1, name='Mher'}
George=Employee {id=2, name='George'}
John=Employee {id=8, name='John'}
Annie=Employee {id=22, name='Annie'}

 

3. 새로운 Map에 결과 저장

추가적으로, 결과집합을 새로운 map에 저장할 수 있다.

Map<String, Employee> result = map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .collect(Collectors.toMap(
    Map.Entry::getKey, 
    Map.Entry::getValue, 
    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

적용

public class UsingStreamAPI {
	public static void main(String[] args) {
		Map<String, Employee> map = new HashMap<>();

		Employee employee1 = new Employee(1L, "Mher");
		map.put(employee1.getName(), employee1);
		Employee employee2 = new Employee(22L, "Annie");
		map.put(employee2.getName(), employee2);
		Employee employee3 = new Employee(8L, "John");
		map.put(employee3.getName(), employee3);
		Employee employee4 = new Employee(2L, "George");
		map.put(employee4.getName(), employee4);
		
		//새 map에 결과 저장
		Map<String, Employee> result = map.entrySet()
				  .stream()
				  .sorted(Map.Entry.comparingByValue())
				  .collect(Collectors.toMap(
				    Map.Entry::getKey, 
				    Map.Entry::getValue, 
				    (oldValue, newValue) -> oldValue, LinkedHashMap::new));
		
		//result map 출력
		Iterator<String> iter = result.keySet().iterator();
		
    	while(iter.hasNext()) {
    		String name = iter.next();
    		Employee employee = result.get(name);
    		System.out.println(name+"="+employee.toString());
    	}
		
	}
}

결과

동일한 값이 result 라는 새로운 map에 저장된다.

Mher=Employee {id=1, name='Mher'}
George=Employee {id=2, name='George'}
John=Employee {id=8, name='John'}
Annie=Employee {id=22, name='Annie'}

 

여기서 결과집합을 LinkedHashMap 에 저장했다는 사실을 기억하자.
기본적으로 Collectors.toMap 은 새로운 HashMap을 리턴한다.
하지만 HashMap이 순서를 유지하지 않더라도 LinkedHashMap이 순서를 유지하기 때문에 정렬 상태로 저장된다.

 

 

 

 

참고 : www.baeldung.com/java-hashmap-sort

728x90