2016-07-02 2 views
1

У меня есть следующий HashMap (HashMap<String, String[]>) и задавался вопросом, есть ли способ удалить определенную строку из массива определенного ключа.Удалить определенное значение из ключа (HashMaps)

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

("key1", new String[]{"A", "B", "C"}) 

Как я могу удалить только B?

+2

У вас есть конкретная причина использования 'String []', а не какой-либо 'Collection '? Было бы намного проще: массивы не предназначены для простого удаления элементов (не в последнюю очередь, они фиксированной длины). –

+0

@ ALToNIC9 Если пользователь ответил на ваш вопрос, пожалуйста, также ** примите ** его ответ ([Принятие ответов: как это работает?] (Https://meta.stackexchange.com/questions/5234/how-does-accepting- ан-ответ-работа)). Если не, пожалуйста, укажите, что остается без ответа, это действительно важная часть StackOverflow, спасибо вам большое. – Zabuza

ответ

2

Вот S простого решения Java:

map.computeIfPresent("key1", (k, v) -> Arrays.stream(v) 
    .filter(s -> !s.equals("B")).toArray(String[]::new)); 
+0

Хорошее использование новых элементов Java 8! Но учтите, что для этого вам нужна Java 8. – Zabuza

+1

@ Zabuza well Java 8 уже в течение более 2 лет. Сейчас это мейнстрим. Если кто-то вынужден использовать Java 7, то они действительно должны устранить причину (обновить/вырезать свой древний контейнер и т. Д.) И воссоединиться с современным миром. – Bohemian

0

Вы бы получить значения для конкретного ключа и удалить данное значение из него, а затем положить его обратно на карту.

public void <K> removeValueFromKey(final Map<K, K[]> map, final K key, final K value) { 
    K[] values = map.get(key); 
    ArrayList<K> valuesAsList = new ArrayList<K>(values.length); 
    for (K currentValue : values) { 
     if (!currentValue.equals(value)) { 
      valuesAsList.add(currentValue); 
     } 
    } 

    K[] newValues = new K[valuesAsList.size()]; 
    newValues = valuesAsList.toArray(newValues); 
    map.put(key, newValues); 
} 

Имейте в виду, что во время выполнения, конечно, является линейным по размеру данного массива . Существует не более быстрый способ, потому что вам нужно перебирать каждый элемент массива, чтобы найти все значения, равные данному значению.

Однако вы могли бы выполнить более быструю реализацию с другими структурами данных, если это практически осуществимо. Например, наборы будут лучше, чем массивы или любая другая структура данных, которая реализует contains, быстрее, чем O (n).

То же самое касается космической сложности; у вас есть пик, где вам нужно держать оба массива в памяти. Это связано с тем, что размер массива нельзя изменить; метод будет строить новый массив. Таким образом, у вас будет два массива в памяти, O(2n).

A Collection<String> может быть лучшим решением в зависимости от того, как часто вы будете называть этот метод, по сравнению с количеством элементов map.

Другое дело, что вы можете ускорить ход, предположив хорошую начальную емкость для ArrayList.

+0

В каком классе 'ArrayUtils' вы ссылаетесь? Я не знаю такого класса в стандартной Java. –

+0

О, мне очень жаль. Конечно ты прав. Вам нужно создать новый массив вручную. Но поскольку вы не знаете новый размер без повторения всех элементов вначале, лучше всего использовать быстрый объект списка в качестве заполнителя. Например, «LinkedList ». Я отредактирую свой первый ответ. – Zabuza

Смежные вопросы