|
1 | 1 | Map Improvements |
2 | 2 | --------- |
| 3 | + |
| 4 | +Map is one the most important data structure. In Java 8, a lot of goodies has been added to the Map API that will make it easy to work with them. We will look at all the enhancements made to them one by one. Every feature is shown along with its JUnit test case. |
| 5 | + |
| 6 | +## Create Map from List |
| 7 | + |
| 8 | +Most of the times we want to create a map from existing data. Let's suppose we have a list of tasks, every task has an id and other associated data like title, description, etc. |
| 9 | + |
| 10 | +```java |
| 11 | +import static java.util.function.Function.identity; |
| 12 | +import static java.util.stream.Collectors.toMap; |
| 13 | + |
| 14 | +@Test |
| 15 | +public void shouldCreateMapFromTaskList() throws Exception { |
| 16 | + Task t1 = new Task("Write blog on Java 8 Map improvements", TaskType.BLOGGING); |
| 17 | + Task t2 = new Task("Write factorial program in Java 8", TaskType.CODING); |
| 18 | + List<Task> tasks = Arrays.asList(t1, t2); |
| 19 | + |
| 20 | + Map<String, Task> taskIdToTaskMap = tasks.stream().collect(toMap(Task::getId, identity())); |
| 21 | + |
| 22 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t1))); |
| 23 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t2))); |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +## Using a different Map implementation |
| 28 | + |
| 29 | + |
| 30 | +The default implementation used by `Collectors.toMap` is `HashMap`. You can also specify your own Map implementation by providing a supplier. |
| 31 | + |
| 32 | +```java |
| 33 | +@Test |
| 34 | +public void shouldCreateLinkedMapFromTaskList() throws Exception { |
| 35 | + Task t1 = new Task("Write blog on Java 8 Map improvements", TaskType.BLOGGING); |
| 36 | + Task t2 = new Task("Write factorial program in Java 8", TaskType.CODING); |
| 37 | + List<Task> tasks = Arrays.asList(t1, t2); |
| 38 | + |
| 39 | + Map<String, Task> taskIdToTaskMap = tasks.stream().collect(toMap(Task::getId, identity(), (k1, k2) -> k1, LinkedHashMap::new)); |
| 40 | + |
| 41 | + assertThat(taskIdToTaskMap, instanceOf(LinkedHashMap.class)); |
| 42 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t1))); |
| 43 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t2))); |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +## Handling duplicates |
| 48 | + |
| 49 | +One thing that we glossed over in the last example was what should happen if there are duplicates. To handle duplicates there is a argument |
| 50 | + |
| 51 | +```java |
| 52 | +@Test |
| 53 | +public void shouldHandleTaskListWithDuplicates() throws Exception { |
| 54 | + Task t1 = new Task("1", "Write blog on Java 8 Map improvements", TaskType.BLOGGING); |
| 55 | + Task t2 = new Task("1", "Write factorial program in Java 8", TaskType.CODING); |
| 56 | + List<Task> tasks = Arrays.asList(t1, t2); |
| 57 | + |
| 58 | + Map<String, Task> taskIdToTaskMap = tasks.stream().collect(toMap(Task::getId, identity())); |
| 59 | + |
| 60 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t1))); |
| 61 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t2))); |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +This test will fail |
| 66 | + |
| 67 | +``` |
| 68 | +java.lang.IllegalStateException: Duplicate key Task{title='Write blog on Java 8 Map improvements', type=BLOGGING} |
| 69 | +``` |
| 70 | + |
| 71 | +You can handle the error by specifying your merge function. |
| 72 | + |
| 73 | +```java |
| 74 | +@Test |
| 75 | +public void shouldHandleTaskListWithDuplicates() throws Exception { |
| 76 | + Task t1 = new Task("1", "Write blog on Java 8 Map improvements", TaskType.BLOGGING); |
| 77 | + Task t2 = new Task("1", "Write factorial program in Java 8", TaskType.CODING); |
| 78 | + List<Task> tasks = Arrays.asList(t1, t2); |
| 79 | + Map<String, Task> taskIdToTaskMap = tasks.stream().collect(toMap(Task::getId, identity(), (k1, k2) -> k2)); |
| 80 | + assertThat(taskIdToTaskMap, hasEntry(notNullValue(), equalTo(t2))); |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +## Create Map from tuples |
| 85 | + |
| 86 | +```java |
| 87 | +public static <T, U> Map<T, U> createMap(SimpleEntry<T, U>... entries) { |
| 88 | + return Stream.of(entries).collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue)); |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +[](https://github.com/igrigorik/ga-beacon) |
0 commit comments