Java 8 Split String и создание карты внутри карты - PullRequest
6 голосов
/ 21 марта 2019

У меня есть строка типа 101-1-5,101-2-4,102-1-5,102-2-5,102-3-5,103-1-4.

Я хочу добавить это в Map<String, Map<String, String>>.

Как: {101={1=5, 2=4}, 102={1=5, 2=5, 3=5}, 103={1=4}}

Как это сделать с помощью потока Java 8?

Я пытался использовать обычную Java. И это прекрасно работает.

public class Util {
    public static void main(String[] args) {

        String samp = "101-1-5,101-2-4,102-1-5,102-2-5,102-3-5,103-1-4";

        Map<String, Map<String, String>> m1 = new HashMap<>();
        Map<String, String> m2 = null;

        String[] items = samp.split(",");

        for(int i=0; i<items.length; i++) {
            String[] subitem = items[i].split("-");
            if(!m1.containsKey(subitem[0]) || m2==null) {
                m2 = new HashMap<>();
            }
            m2.put(subitem[1], subitem[2]);
            m1.put(subitem[0], m2);
        }
        System.out.println(m1);
    }
}

Ответы [ 2 ]

6 голосов
/ 22 марта 2019

Для этого вы можете использовать следующий фрагмент:

Map<String, Map<String, String>> result = Arrays.stream(samp.split(","))
        .map(i -> i.split("-"))
        .collect(Collectors.groupingBy(a -> a[0], Collectors.toMap(a -> a[1], a -> a[2])));

Сначала он создает поток ваших элементов, которые сопоставляются с потоком массивов, содержащих подэлементы.В конце вы собираете все, используя group by в первом подпункте, и создаете внутреннюю карту со вторым значением в качестве ключа и последним в качестве значения.

Результат:

{101={1=5, 2=4}, 102={1=5, 2=5, 3=5}, 103={1=4}}
4 голосов
/ 22 марта 2019
Map<String, Map<String, String>> map = Arrays.stream(samp.split(","))
        .map(s -> s.split("-"))
        .collect(Collectors.toMap(
                o -> o[0],
                o -> Map.of(o[1], o[2]),
                (m1, m2) -> Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));

Map.of из Java 9, вы можете использовать AbstractMap.SimpleEntry, если вы находитесь в Java 8.

Ответ Самуэля лучше , хотя, намного лаконичнее.

...