Гуавы?
Это первая из серии публикаций, в которых я попытаюсь объяснить и изучить потрясающую библиотеку Java на языке гуавы от Google.
Я впервые наткнулся на Гуаву, когда искал универсальные версии коллекций Apache Commons — мне был нужен Bimap и мне Bimap свой код с помощью забросов — однако то, что я обнаружил, было намного лучше.
Он содержит не только различные реализации более сложных (но полезных) типов коллекций — Multimaps , Multisets , Bimaps — о которых я расскажу подробно, но также и средства поддержки более функционального стиля программирования с неизменяемыми коллекциями, а также функции и предиката объекты. Это полностью изменило то, как я пишу Java, и в то же время заставило меня все больше расстраиваться из-за неуклюжего синтаксиса Java, что я собираюсь исследовать в следующих статьях.
Во всяком случае, достаточно с введением и с хорошим материалом. Первое, на что я хотел бы взглянуть, это Multimap, которая, вероятно, является единственной функцией Guava, которую я использовал чаще всего.
Mutlimaps
Итак, как часто вам нужна структура данных, как показано ниже?
|
1
2
|
Map<String,List<MyClass>> myClassListMap test2 = new HashMap<String,List<MyClass>>() |
Если вы похожи на меня, довольно часто. И разве вы не пишете один и тот же шаблонный код снова и снова?
Чтобы поместить пару ключ / значение в эту карту, необходимо сначала проверить, существует ли список для вашего ключа, и не создает ли он его. Вы закончите тем, что написали что-то вроде следующего:
|
1
2
3
4
5
6
7
8
|
void putMyObject(String key, Object value) { List<Object> myClassList = myClassListMap.get(key); if(myClassList == null) { myClassList = new ArrayList<object>(); myClassListMap.put(key,myClassList); } myClassList.add(value);} |
Немного боли, а что, если вам нужны методы для проверки существования значения, или удаления значения, или даже итерации по всей структуре данных. Это может быть довольно много кода.
Никогда не бойся Гуава здесь!
Как и стандартные коллекции Java, Guava определяет несколько интерфейсов и соответствующих реализаций. Обычно вы хотите закодировать интерфейс и беспокоиться о реализации только при его создании. В этом случае нас интересуют мультикарты.
Таким образом, используя мультикарту, мы могли бы заменить объявление структуры данных следующим:
|
1
|
Multimap<String,Object> myMultimap = ArrayListMultimap.create(); |
Здесь есть несколько вещей, на которые стоит обратить внимание. Объявление универсального типа должно выглядеть очень знакомым, именно так вы бы объявили карту нормалей.
Возможно, вы ожидали увидеть new ArrayListMultimap<String,Object>() в правой части равенства. Что ж, все реализации коллекций Guava предлагают метод create , который обычно более лаконичен и имеет то преимущество, что вам не нужно дублировать информацию общего типа.
Guava фактически добавляет аналогичные функциональные возможности к стандартным коллекциям Java. Например, если вы изучите com.google.common.collect.Lists , вы увидите статические newArrayList() и newLinkedList() , так что вы можете воспользоваться этой краткостью даже со стандартными коллекциями Java. (Я постараюсь рассказать об этом более подробно в следующем посте).
Итак, мы объявили и создали экземпляр мультикарты, как нам их использовать? Легко, как обычная карта!
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public class MutliMapTest { public static void main(String... args) { Multimap<String, String> myMultimap = ArrayListMultimap.create(); // Adding some key/value myMultimap.put('Fruits', 'Bannana'); myMultimap.put('Fruits', 'Apple'); myMultimap.put('Fruits', 'Pear'); myMultimap.put('Vegetables', 'Carrot'); // Getting the size int size = myMultimap.size(); System.out.println(size); // 4 // Getting values Collection<string> fruits = myMultimap.get('Fruits'); System.out.println(fruits); // [Bannana, Apple, Pear] Collection<string> vegetables = myMultimap.get('Vegetables'); System.out.println(vegetables); // [Carrot] // Iterating over entire Mutlimap for(String value : myMultimap.values()) { System.out.println(value); } // Removing a single value myMultimap.remove('Fruits','Pear'); System.out.println(myMultimap.get('Fruits')); // [Bannana, Pear] // Remove all values for a key myMultimap.removeAll('Fruits'); System.out.println(myMultimap.get('Fruits')); // [] (Empty Collection!) }} |
Вам может быть интересно узнать, почему метод get возвращает Collection а не List , что было бы гораздо более полезным. Это действительно так. Проблема в том, что существует несколько различных реализаций, некоторые из них используют Lists- ArrayListMultimap , LinkedListMultimap и т. Д., А некоторые используют наборы — HashMultimap , TreeMultimap и другие.
Чтобы справиться с этим — если вам нужно работать непосредственно со списками или наборами на карте, — определено несколько подынтерфейсов. ListMultimap , SetMultimap и SortedSetMultimap . Все они делают то, что вы ожидаете, и их методы, которые возвращают коллекции, возвращают один из подходящих типов.
т.е.
|
1
2
3
|
ListMutlimap<String,String> myMutlimap = ArrayListMultimap.create();List<string> myValues = myMutlimap.get('myKey'); // Returns a List, not a Collection. |
Это в основном все, что есть для них. Я рекомендую взглянуть на API: http://docs.guava-libraries.googlecode.com/git-history/release09/javadoc/com/google/common/collect/Multimap.html , где вы можете найти различные реализации, вы должен быть в состоянии найти тот, который соответствует вашим потребностям.
Ссылка: Multimaps — Google Guava от нашего партнера JCG Тома Джеффериса в блоге Tom’s Programming Blog .