Как изменить / удалить два ArrayLists, которые являются элементами в HashMap? - PullRequest
0 голосов
/ 22 сентября 2019

Описание

У меня есть HashMap<ArrayLists<Integer>, <Integer>>, похожее на следующее:

{[1]=1, [3]=1, [1, 4, 6]=1, [0, 2, 3, 5, 6]=3, [6]=1}

Мне нужно сравнить, изменить / удалить элементы в разных ArrayLists (то есть элементы вHashMap), пока не будут выполнены следующие условия:

  1. Каждый элемент ArrayList принадлежит только одному списку, список с наибольшим Value.
  2. Если Value = 1для всех списков, содержащих этот элемент, элемент ArrayList относится к одноэлементному списку.
  3. Если ArrayList становится пустым, его следует удалить из HashMap.

Таким образом, для приведенного выше примера должно получиться следующее:

{[1]=1, [4]=1, [0, 2, 3, 5, 6]=3}

Я привык работать с массивами массивов, чтобы делать подобные вещи.На этот раз было бы полезно иметь функции HashMap и ArrayList, но в настоящее время мне неудобно делать более сложные модификации этих типов данных.Я сделал несколько попыток и должен был предотвратить как ConcurrentModificationException , так и IllegalStateException , но до сих пор не достиг полного успеха.У меня также есть ощущение, что мои реализации становятся ненужными сложными, поэтому я был бы очень признателен, если бы кто-то имел опыт в реализации таких вещей.


Примечание о HashMap

Причина, по которой я использую HashMap (не стесняйтесь предлагать что-то более подходящее), заключается в том, что Value является подсчетом того, сколько раз ArrayList было "встречено" и добавлено к HashMap.


Минимальный пример

Минимальный пример моей последней нерабочей (IndexOutOfBoundsException) попытки.Обратите внимание, что создание HashMap и ArrayList s выполняется здесь статически, поскольку в моей реальной программе это делается недетерминированным образом на основе содержимого файла.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        Map<List<Integer>, Integer> example = new HashMap<>(7);
        List<Integer> list = new ArrayList<>(7);
        list.add(1);
        example.put(list, 1);
        list = new ArrayList<>(7);
        list.add(3);
        example.put(list, 1);
        list = new ArrayList<>(7);
        list.add(1);
        list.add(4);
        list.add(6);
        example.put(list, 1);
        list = new ArrayList<>(7);
        list.add(0);
        list.add(2);
        list.add(3);
        list.add(5);
        list.add(6);
        example.put(list, 3);
        list = new ArrayList<>(7);
        list.add(6);
        example.put(list, 1);
        System.err.println(example);

        Map<List<Integer>, Integer> copy = new HashMap<>(example);
        for (Map.Entry<List<Integer>, Integer> outer : example.entrySet()) {
            for (Map.Entry<List<Integer>, Integer> inner : copy
                .entrySet()) {
                for (int i : outer.getKey()) {
                    int oSize = outer.getKey().size();
                    int iSize = inner.getKey().size();
                    int oValue = outer.getValue();
                    int iValue = inner.getValue();

                    if (!(inner.equals(outer)) && (inner.getKey()
                        .contains(i))) {
                        if (oSize == 1) {
                            if (oValue < iValue) {
                                outer.getKey().remove(i);
                            } else {
                                inner.getKey().remove(i);
                            }
                        } else if (iSize == 1) {
                            if (iValue < oValue) {
                                outer.getKey().remove(i);
                            } else {
                                inner.getKey().remove(i);
                            }
                        } else {
                            if (oValue < iValue) {
                                outer.getKey().remove(i);
                            } else {
                                inner.getKey().remove(i);
                            }
                        }
                    }
                }
            }
        }
    }
}

Ответы [ 2 ]

2 голосов
/ 22 сентября 2019

По моему плохому мнению, я рекомендую упорядочить значение карты (согласно наибольшему значению) в 1-м раунде, а затем завершить нашу работу по удалению с помощью бизнес-логики.

Например:

        Map<List<Integer>, Integer> example = new HashMap<>();
        // data initialize

        // order by Map.Entry::getValue desc
        List<Map.Entry<List<Integer>, Integer>> collect = example.entrySet()
                .stream()
                .sorted((e1, e2) -> e2.getValue() - e1.getValue())
                .collect(Collectors.toList());

        // remove duplicate list element in Map.Entry::getKey
        Set<Integer> tmp = new HashSet<>();
        // collect.forEach(c -> c.getKey().removeIf(next -> !tmp.add(next)));
        example = collect
                .stream()
                .filter(c -> {
                    c.getKey().removeIf(next -> !tmp.add(next));
                    return !c.getKey().isEmpty();
                })
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
2 голосов
/ 22 сентября 2019

Весьма необычно использовать ArrayList в качестве ключа для HashMap ( Являются ли изменяемые ключи hashmap опасной практикой? ).Но при условии, что с вами все в порядке, чтобы обновить запись на карте, вы можете удалить ее (и список, и целое число) из hasmap, создать новый список с вашими изменениями, а затем повторно вставить, если необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...