guava 는 google 에서 제공하는 다양한 자료구조와 유틸리티들을 모아둔 라이브러리이다. 최근 map 자료구조를 사용하면서 하나의 key 에 value 가 리스트로 붙는 자료구조가 필요하게 되었다. 그냥 자바 코드로 생각하면 다음과 같은 모양이다.
Map<String, List<String>> multimap = new HashMap<String, List<String>>(); multimap.put( "key", new ArrayList<String>() ); multimap.get( "key" ).add("value1"); multimap.get( "key" ).add("value2");
guava 의 Multimap 자료 구조를 이용하면 다음과 같이 단순화 할 수 있다.
Multimap<String, String> multimap = ArrayListMultimap.create(); multimap.put("key", "value1"); multimap.put("key", "value2");
List 와 Map 에도 다양한 implementation 이 있듯이 guava 에서도 multimap 에 대한 다양한 implementation 이 존재한다.
하지만 모든 기대를 충족할 수는 없으니 좀 더 custom 된 multimap 이 필요하게 되었다. 바로 key 는 알파벳순으로 정렬이 되지만 value 는 삽입된 순서대로 정렬이 되는 구조의 multimap 이다. 이러한 multimap 을 위해서 각 특성을 가진 collection 을 인자로 받아서 multimap 을 선언할 수 있도록 Multimaps.newMultimap() 이라는 인터페이스가 존재한다. key 는 정렬을 할 수 있도록 TreeMap 을 사용하였고 value 부분은 삽입 순서만 지키면 되어서 ArrayList 를 사용하였다.
Multimap<String, String> options = Multimaps.newMultimap( new TreeMap<String, Collection<String>>(), new Supplier<List<String>>() { @Override public List<String> get() { return Lists.newArrayList(); } }); options.put("z", "d"); options.put("z", "a"); options.put("b", "c"); options.put("b", "e"); options.put("b", "d"); options.put("a", "c"); options.put("a", "b"); final Iterator<String> iter = options.keySet().iterator(); while ( iter.hasNext() ){ String s = iter.next(); System.out.println(s + " / " + options.get(s) ); }