Как да конвертирате списък в карта в Java

1. Общ преглед

Преобразуването на списък в карта е често срещана задача. В този урок ще разгледаме няколко начина за това.

Ще приемем, че всеки елемент от Списъка има идентификатор, който ще се използва като ключ в получената Карта .

2. Примерна структура на данните

Първо, нека моделираме елемента:

public class Animal { private int id; private String name; // constructor/getters/setters }

Полето id е уникално, следователно можем да го направим ключово.

Нека започнем да конвертираме по традиционния начин.

3. Преди Java 8

Очевидно можем да конвертираме Списък в Карта, използвайки основните методи на Java:

public Map convertListBeforeJava8(List list) { Map map = new HashMap(); for (Animal animal : list) { map.put(animal.getId(), animal); } return map; }

Нека тестваме преобразуването:

@Test public void whenConvertBeforeJava8_thenReturnMapWithTheSameElements() { Map map = convertListService .convertListBeforeJava8(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); }

4. С Java 8

Започвайки с Java 8, можем да конвертираме списък в карта, използвайки потоци и колектори :

 public Map convertListAfterJava8(List list) { Map map = list.stream() .collect(Collectors.toMap(Animal::getId, animal -> animal)); return map; }

Отново, нека се уверим, че преобразуването е направено правилно:

@Test public void whenConvertAfterJava8_thenReturnMapWithTheSameElements() { Map map = convertListService.convertListAfterJava8(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); }

5. Използване на библиотеката Guava

Освен основната Java, ние можем да използваме библиотеки на трети страни за преобразуване.

5.1. Maven конфигурация

Първо, трябва да добавим следната зависимост към нашия pom.xml :

 com.google.guava guava 23.6.1-jre 

Най-новата версия на тази библиотека винаги може да бъде намерена тук.

5.2. Преобразуване с Maps.uniqueIndex ()

На второ място, нека използваме метода Maps.uniqueIndex () , за да преобразуваме списък в карта :

public Map convertListWithGuava(List list) { Map map = Maps .uniqueIndex(list, Animal::getId); return map; }

И накрая, нека тестваме преобразуването:

@Test public void whenConvertWithGuava_thenReturnMapWithTheSameElements() { Map map = convertListService .convertListWithGuava(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); } 

6. Използване на библиотека Apache Commons

Ние също можем да направим преобразуване сметод на библиотеката Apache Commons.

6.1. Maven конфигурация

Първо, нека включим зависимостта на Maven:

 org.apache.commons commons-collections4 4.2 

Най-новата версия на тази зависимост е достъпна тук.

6.2. MapUtils

На второ място, ще направим преобразуването с помощта на MapUtils.populateMap () :

public Map convertListWithApacheCommons2(List list) { Map map = new HashMap(); MapUtils.populateMap(map, list, Animal::getId); return map; }

И накрая, нека се уверим, че работи както се очаква:

@Test public void whenConvertWithApacheCommons2_thenReturnMapWithTheSameElements() { Map map = convertListService .convertListWithApacheCommons2(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); }

7. Конфликт на ценности

Нека проверим какво се случва, ако полето за идентификатор не е уникално.

7.1. Списък на животни с дублирани Id ите

Първо, нека създадем списък с животни с не уникални идентификатори :

@Before public void init() { this.duplicatedIdList = new ArrayList(); Animal cat = new Animal(1, "Cat"); duplicatedIdList.add(cat); Animal dog = new Animal(2, "Dog"); duplicatedIdList.add(dog); Animal pig = new Animal(3, "Pig"); duplicatedIdList.add(pig); Animal cow = new Animal(4, "Cow"); duplicatedIdList.add(cow); Animal goat= new Animal(4, "Goat"); duplicatedIdList.add(goat); }

Както е показано по-горе, кравата и козата имат една и съща идентификация .

7.2. Проверка на поведението

Java Map‘s put() method is implemented so that the latest added value overwrites the previous one with the same key.

For this reason, the traditional conversion and Apache Commons MapUtils.populateMap() behave in the same way:

@Test public void whenConvertBeforeJava8_thenReturnMapWithRewrittenElement() { Map map = convertListService .convertListBeforeJava8(duplicatedIdList); assertThat(map.values(), hasSize(4)); assertThat(map.values(), hasItem(duplicatedIdList.get(4))); } @Test public void whenConvertWithApacheCommons_thenReturnMapWithRewrittenElement() { Map map = convertListService .convertListWithApacheCommons(duplicatedIdList); assertThat(map.values(), hasSize(4)); assertThat(map.values(), hasItem(duplicatedIdList.get(4))); }

As can be seen, the goat overwrites the cow with the same id.

Unlike that, Collectors.toMap() and MapUtils.populateMap() throw IllegalStateException and IllegalArgumentException respectively:

@Test(expected = IllegalStateException.class) public void givenADupIdList_whenConvertAfterJava8_thenException() { convertListService.convertListAfterJava8(duplicatedIdList); } @Test(expected = IllegalArgumentException.class) public void givenADupIdList_whenConvertWithGuava_thenException() { convertListService.convertListWithGuava(duplicatedIdList); }

8. Conclusion

В тази бърза статия разгледахме различни начини за преобразуване на списък в карта, давайки примери с основната Java, както и някои популярни библиотеки на трети страни.

Както обикновено, пълният изходен код е достъпен в GitHub.