Статьи

Google Guava BiMaps

Далее в моем туре по Гуаве , BiMap , еще один полезный тип коллекции. Это довольно просто, BiMap — это просто двусторонняя карта.

Инвертирование карты

Обычная карта Java — это набор ключей и значений, и вы можете искать значения по ключу, что очень полезно, например, допустим, я хотел создать (очень элементарный) словарь британского английского в американский английский:

1
2
3
4
Map<String,String> britishToAmerican = Maps.newHashMap();
britishToAmerican.put('aubergine','egglant');
britishToAmerican.put('courgette','zucchini');
britishToAmerican.put('jam','jelly');

Но что, если вам нужен словарь с американского на британский? Ну, вы можете написать код для инвертирования карты:

1
2
3
4
5
6
7
8
   // Generic method to reverse map.
   public %lt;S,T> Map<T,S> getInverseMap(Map<S,T> map) {
 Map<T,S> inverseMap = new HashMap<T,S>();
 for(Entry<S,T> entry: map.entrySet()) {
  inverseMap.put(entry.getValue(), entry.getKey());
 }
 return inverseMap;
}

Это сработает, но есть несколько сложностей, о которых вам, возможно, придется подумать.

  • Как мы обрабатываем повторяющиеся значения в исходной карте? На данный момент они будут перезаписаны на обратной карте.
  • Что если мы хотим поместить новую запись в обратную карту? Мы также должны обновить оригинальную карту! Это может стать раздражающим.

BiMaps

Ну, угадай что? Это такая ситуация, для которой разработан BiMap! И вот как вы можете использовать это.

01
02
03
04
05
06
07
08
09
10
11
12
13
BiMap<String,String> britishToAmerican = HashBiMap.create();
 
// Initialise and use just like a normal map
britishToAmerican.put('aubergine','egglant');
britishToAmerican.put('courgette','zucchini');
britishToAmerican.put('jam','jelly');
 
System.out.println(britishToAmerican.get('aubergine')); // eggplant
 
BiMap<String,String> americanToBritish = britishToAmerican.inverse();
 
System.out.println(americanToBritish.get('eggplant')); // aubergine
System.out.println(americanToBritish.get('zucchini')); // courgette

Довольно просто, но есть несколько вещей, на которые стоит обратить внимание.

Обеспечение уникальности

Во-первых, BiMap обеспечивает уникальность своих значений и даст вам исключение недопустимого аргумента, если вы попытаетесь вставить дублирующее значение, т.е.

1
2
britishToAmerican.put('pudding','dessert');
britishToAmerican.put('sweet','dessert'); // IllegalArgumentException.

Если вам нужно добавить уже добавленные значения, есть метод forcePut , который перезапишет запись с повторяющимся значением.

1
2
3
4
britishToAmerican.put('pudding','dessert');
britishToAmerican.forcePut('sweet','dessert');  // Overwrites the previous entry
System.out.println(britishToAmerican.get('sweet')); // dessert
System.out.println(britishToAmerican.get('pudding')); // null

Обратный метод

Другая важная вещь для понимания — inverse метод, он возвращает обратную BiMap, то есть карту с переключенными ключами и значениями.
Теперь эта обратная карта — это не просто новая карта, как, например, мой предыдущий метод reverseMap. Это на самом деле вид на оригинальную карту. Это означает, что любые последующие изменения обратного метода будут влиять на исходную карту!

1
2
3
americanToBritish.put('potato chips','crisps');
System.out.println(britishToAmerican.containsKey('crisps')); // true
System.out.println(britishToAmerican.get('crisps')); // potato chips

Так что это BiMap, как я уже сказал, довольно просто. Как обычно, доступно несколько реализаций, и, как всегда, я рекомендую взглянуть на полную документацию по API:
http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/collect/BiMap.html

Ссылка: Google Guava BiMaps от нашего партнера JCG Тома Джеффериса в блоге Tom’s Programming Blog .