Сортировать содержимое списка в новые списки - PullRequest
0 голосов
/ 12 октября 2018

У меня есть несортированный список с неизвестным количеством элементов в диапазоне 1000. Все эти элементы содержат метку, которая определяет, куда они должны идти.Чтобы не повторять каждый элемент списка несколько раз, я хочу разбить этот список на определенное количество подсписков, которые содержат только элементы определенных меток.

List<Item> allItems = getItemsFromSomewhere();

List<Item> itemsLabeledA1 = new ArrayList<>();
List<Item> itemsLabeledA2 = new ArrayList<>();
List<Item> itemsLabeledB1 = new ArrayList<>();
...
List<Item> itemsLabeledL3 = new ArrayList<>();

Чтобы еще больше усложнить проблему, некоторые изсписки требуют добавления диапазона элементов, поэтому каждый элемент помечен как-то вроде «A1», «A2», «A3».Эти списки требуют добавления каждого элемента с A-меткой.Однако не все ярлыки имеют эти сводные списки.Возможно, мне придется объединить все элементы, помеченные буквой «А», при этом не объединяя все элементы, помеченные буквой «В», и в то же время отсортировать в своих списках А1, В1 и т. Д.

Учитывая приведенный выше пример, как элегантно разделитьполный список за одну итерацию?Моей первоначальной мыслью было использование ifs или блока переключателей, но это ужасное решение.

allItems.forEach(item -> {
    if (item.getLabel().contains("A1")) { 
       itemsLabeledA1.add(item);
       allItemsLabeledA.add(item);
    }
    else if (item.getLabel().contains("B1")) itemsLabeledB1.add(item);
    ...
    else if (item.getLabel().contains("L3")) itemsLabeledL3.add(item);
});

Есть ли лучший способ?

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Я бы использовал groupingBy в двух отдельных операциях потоковой передачи:

Map<String, List<Item>> allByLabel = allItems.stream().collect(
    Collectors.groupingBy(Item::getLabel));

Map<String, List<Item>> allByLabelStart = allItems.stream().collect(
    Collectors.groupingBy(item -> item.getLabel().substring(0, 1)));
0 голосов
/ 12 октября 2018

Кажется, вы классифицируете ваши предметы.Для этого вам нужно создать разные группы согласно вашей спецификации, а затем добавить каждый элемент в свою группу.Если я правильно понял ваше требование, вы могли бы выполнить это следующим образом:

Map<String, List<Item>> map = new LinkedHashMap<>(); // keeps insertion order
allItems.forEach(it -> {
    String lbl = it.getLabel();
    map.computeIfAbsent(lbl, k -> new ArrayList<>()).add(it);
    if (needsToBeAggregated(lbl)) {
        map.computeIfAbsent(lbl.substring(0, 1), k -> new ArrayList<>()).add(it);
    }
});

Где boolean needsToBeAggregated(String label) - это какой-то метод, в котором вы решаете, следует ли добавить элемент в совокупную группу или нет.

Это решение не использует потоки, но вместо этого используется метод Java 8 Map.computeIfAbsent.

0 голосов
/ 12 октября 2018

Может быть, вы можете попробовать использовать HashMap, где ключом являются метки, а значениями являются подсписки?

HashMap<String, List<Item>> map = new HashMap<String, List<Item>>();
for (String label : labels) {
    map.put(label, new List<Item>);
}
allItems.forEach(item -> {
    String label = item.getLabel();
    map.get(label).add(item);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...