Далее в моем туре по Гуаве , 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 .