Это первая из серии публикаций, в которых я попытаюсь объяснить и изучить потрясающую библиотеку Java на языке гуавы от Google .
Я впервые наткнулся на Гуаву, когда искал универсальные версии коллекций Apache Commons — мне был нужен Bimap, и мне надоело перетаскивать свой код с помощью забросов — однако то, что я обнаружил, было намного лучше.
Мало того, что он содержит различные реализации более сложных (но полезные) типов коллекций — Multimaps , мультинаборы , Bimaps — что я буду обсуждать в деталях, но и средства для поддержки более функционального стиля программирования с неизменными коллекциями, а также функцию и предикатобъекты. Это полностью изменило то, как я пишу Java, и в то же время заставило меня все больше расстраиваться из-за неуклюжего синтаксиса Java, что я собираюсь исследовать в следующих статьях.
Во всяком случае, достаточно с введением и с хорошим материалом. Первое, на что я хотел бы взглянуть, это Multimap, которая, вероятно, является единственной функцией Guava, которую я использовал чаще всего.
Mutlimaps
Итак, как часто вам нужна структура данных, как показано ниже?
Map<String,List<MyClass>> myClassListMap test2 = new HashMap<String,List<MyClass>>()
Если вы похожи на меня, довольно часто. И разве вы не пишете один и тот же шаблонный код снова и снова?
Чтобы поместить пару ключ / значение в эту карту, необходимо сначала проверить, существует ли список для вашего ключа, и не создает ли он его. Вы закончите тем, что написали что-то вроде следующего:
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 определяет несколько интерфейсов и соответствующих реализаций. Обычно вы хотите закодировать интерфейс и беспокоиться о реализации только при его создании. В этом случае нас интересуют мультикарты.
Таким образом, используя мультикарту, мы могли бы заменить объявление структуры данных следующим:
Multimap<String,Object> myMultimap = ArrayListMultimap.create();
Здесь есть несколько вещей, на которые стоит обратить внимание. Объявление универсального типа должно выглядеть очень знакомым, именно так вы бы объявили карту нормалей.
Возможно, вы ожидали увидеть новый ArrayListMultimap <String, Object> () в правой части равенства. Что ж, все реализации коллекций Guava предлагают метод create, который обычно более лаконичен и имеет то преимущество, что вам не нужно дублировать информацию общего типа.
Guava фактически добавляет аналогичные функциональные возможности к стандартным коллекциям Java Например, если вы изучите com.google.common.collect.Lists , вы увидите статические методы newArrayList () и newLinkedList (), так что вы можете воспользоваться этой краткостью даже со стандартными коллекциями Java. (Я постараюсь рассказать об этом более подробно в следующем посте).
Итак, мы объявили и создали экземпляр мультикарты, как нам их использовать? Легко, как обычная карта!
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, что было бы гораздо более полезным. Это действительно так. Проблема в том, что существует несколько различных реализаций, некоторые используют списки — ArrayListMultimap, LinkedListMultimap и т. Д. — а некоторые используют наборы — HashMultimap, TreeMultimap и другие.
Чтобы справиться с этим — если вам нужно работать непосредственно со списками или наборами на карте, — определено несколько подынтерфейсов. ListMultimap, SetMultimap и SortedSetMultimap. Все они делают то, что вы ожидаете, и их методы, которые возвращают коллекции, возвращают один из подходящих типов.
т.е.
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 , где вы можете найти различные реализации, вы должен быть в состоянии найти тот, который соответствует вашим потребностям.
Итак, пока что все. В моем следующем посте я буду представлять BiMap