Skip to content

Commit d777c73

Browse files
committed
Consistent handling of empty List entries in LinkedMultiValueMap
Closes gh-22912
1 parent 0ef6117 commit d777c73

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

spring-core/src/main/java/org/springframework/util/LinkedMultiValueMap.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,8 @@
3434
* @author Arjen Poutsma
3535
* @author Juergen Hoeller
3636
* @since 3.0
37+
* @param <K> the key type
38+
* @param <V> the value element type
3739
*/
3840
public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializable, Cloneable {
3941

@@ -73,6 +75,12 @@ public LinkedMultiValueMap(Map<K, List<V>> otherMap) {
7375

7476
// MultiValueMap implementation
7577

78+
@Override
79+
public V getFirst(K key) {
80+
List<V> values = this.targetMap.get(key);
81+
return (values != null && !values.isEmpty() ? values.get(0) : null);
82+
}
83+
7684
@Override
7785
public void add(K key, V value) {
7886
List<V> values = this.targetMap.get(key);
@@ -83,12 +91,6 @@ public void add(K key, V value) {
8391
values.add(value);
8492
}
8593

86-
@Override
87-
public V getFirst(K key) {
88-
List<V> values = this.targetMap.get(key);
89-
return (values != null ? values.get(0) : null);
90-
}
91-
9294
@Override
9395
public void set(K key, V value) {
9496
List<V> values = new LinkedList<V>();
@@ -107,7 +109,10 @@ public void setAll(Map<K, V> values) {
107109
public Map<K, V> toSingleValueMap() {
108110
LinkedHashMap<K, V> singleValueMap = new LinkedHashMap<K,V>(this.targetMap.size());
109111
for (Entry<K, List<V>> entry : this.targetMap.entrySet()) {
110-
singleValueMap.put(entry.getKey(), entry.getValue().get(0));
112+
List<V> values = entry.getValue();
113+
if (values != null && !values.isEmpty()) {
114+
singleValueMap.put(entry.getKey(), values.get(0));
115+
}
111116
}
112117
return singleValueMap;
113118
}

spring-core/src/test/java/org/springframework/util/LinkedMultiValueMapTests.java

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,26 +28,35 @@
2828

2929
/**
3030
* @author Arjen Poutsma
31+
* @author Juergen Hoeller
3132
*/
3233
public class LinkedMultiValueMapTests {
3334

34-
private final LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
35+
private final LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
3536

3637

3738
@Test
3839
public void add() {
3940
map.add("key", "value1");
4041
map.add("key", "value2");
4142
assertEquals(1, map.size());
42-
List<String> expected = new ArrayList<String>(2);
43+
List<String> expected = new ArrayList<>(2);
4344
expected.add("value1");
4445
expected.add("value2");
4546
assertEquals(expected, map.get("key"));
4647
}
4748

49+
@Test
50+
public void set() {
51+
map.set("key", "value1");
52+
map.set("key", "value2");
53+
assertEquals(1, map.size());
54+
assertEquals(Collections.singletonList("value2"), map.get("key"));
55+
}
56+
4857
@Test
4958
public void getFirst() {
50-
List<String> values = new ArrayList<String>(2);
59+
List<String> values = new ArrayList<>(2);
5160
values.add("value1");
5261
values.add("value2");
5362
map.put("key", values);
@@ -56,22 +65,40 @@ public void getFirst() {
5665
}
5766

5867
@Test
59-
public void set() {
60-
map.set("key", "value1");
61-
map.set("key", "value2");
62-
assertEquals(1, map.size());
63-
assertEquals(Collections.singletonList("value2"), map.get("key"));
68+
public void getFirstWithEmptyList() {
69+
map.put("key", Collections.emptyList());
70+
assertNull(map.getFirst("key"));
71+
assertNull(map.getFirst("other"));
72+
}
73+
74+
@Test
75+
public void toSingleValueMap() {
76+
List<String> values = new ArrayList<>(2);
77+
values.add("value1");
78+
values.add("value2");
79+
map.put("key", values);
80+
Map<String, String> svm = map.toSingleValueMap();
81+
assertEquals(1, svm.size());
82+
assertEquals("value1", svm.get("key"));
83+
}
84+
85+
@Test
86+
public void toSingleValueMapWithEmptyList() {
87+
map.put("key", Collections.emptyList());
88+
Map<String, String> svm = map.toSingleValueMap();
89+
assertEquals(0, svm.size());
90+
assertNull(svm.get("key"));
6491
}
6592

6693
@Test
6794
public void equals() {
6895
map.set("key1", "value1");
6996
assertEquals(map, map);
70-
MultiValueMap<String, String> o1 = new LinkedMultiValueMap<String, String>();
97+
MultiValueMap<String, String> o1 = new LinkedMultiValueMap<>();
7198
o1.set("key1", "value1");
7299
assertEquals(map, o1);
73100
assertEquals(o1, map);
74-
Map<String, List<String>> o2 = new HashMap<String, List<String>>();
101+
Map<String, List<String>> o2 = new HashMap<>();
75102
o2.put("key1", Collections.singletonList("value1"));
76103
assertEquals(map, o2);
77104
assertEquals(o2, map);

0 commit comments

Comments
 (0)