I am writing a Java function that checks if the items of a list are unique (depending of an id
member).
I have a Java 7 implementation that works, but it is not using streams, filter and joins. I think the code can be improved.
Case 1: empty list => OK
Case 2: all ids are different => OK
+---------+-------+
| baf18c4 | Item1 |
| c5e4623 | Item2 |
| bf1932f | Item3 |
+---------+-------+
No message expected.
Case 3: one id is duplicate (3 times each) => message expected
+---------+-------+
| baf18c4 | Item1 |
| c5e4623 | Item2 |
| baf18c4 | Item3 |
| baf18c4 | Item4 |
+---------+-------+
Expected message:
Some of the items are sharing the same code: 'baf18c4' used by {Item1, Item3, Item4}
Case 4: two ids is duplicate (2 times each) => message expected
+---------+-------+
| baf18c4 | Item1 |
| c5e4623 | Item2 |
| baf18c4 | Item3 |
| bf1932f | Item4 |
| c5e4623 | Item5 |
+---------+-------+
Some of the items are sharing the same code: 'baf18c4' used by {Item1, Item3}, 'c5e4623' used by {Item2, Item5}
Code
package tmp;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.junit.Test;
public class Snippet {
private static String verifyItems(List<Item> items) {
Map<String, List<Item>> map = new HashMap<>();
for (Item item : items) {
String key = item.getCode();
List<Item> list;
if (map.containsKey(key)) {
list = map.get(key);
}
else {
list = new ArrayList<>();
map.put(key, list);
}
list.add(item);
}
boolean isFirst = true;
StringBuilder sb = new StringBuilder();
for (Entry<String, List<Item>> e : map.entrySet()) {
if (e.getValue().size() > 1) {
if (isFirst) {
sb.append("Some of the items are sharing the same code: ");
}
else {
sb.append(", ");
}
isFirst = false;
sb.append("'" + e.getKey() + "' used by ");
sb.append(e.getValue().stream().map(i -> i.getDescription())
.collect(Collectors.joining(", ", "{", "}")));
}
}
return sb.toString();
}
@Test
public void testEmpty() throws Exception {
assertEquals("", verifyItems(Collections.emptyList()));
}
@Test
public void testOk() throws Exception {
List<Item> items = Arrays.asList(
new Item("baf18c4", "Item1"),
new Item("c5e4623", "Item2"),
new Item("bf1932f", "Item3"));
assertEquals("", verifyItems(items));
}
@Test
public void testDuplicate() throws Exception {
List<Item> items = Arrays.asList(
new Item("baf18c4", "Item1"),
new Item("c5e4623", "Item2"),
new Item("baf18c4", "Item3"),
new Item("baf18c4", "Item4"));
assertEquals("Some of the items are sharing the same code: 'baf18c4' used by {Item1, Item3, Item4}", verifyItems(items));
}
@Test
public void testDuplicate2() throws Exception {
List<Item> items = Arrays.asList(
new Item("baf18c4", "Item1"),
new Item("c5e4623", "Item2"),
new Item("baf18c4", "Item3"),
new Item("bf1932f", "Item4"),
new Item("c5e4623", "Item5"));
assertEquals("Some of the items are sharing the same code: 'baf18c4' used by {Item1, Item3}, 'c5e4623' used by {Item2, Item5}", verifyItems(items));
}
public static class Item {
private String code;
private String description;
public Item(String code, String description) {
super();
this.code = code;
this.description = description;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
}
}