является набор ключей Java HashMap () итеративным последовательным порядком?

GCC повсеместен. Этому доверяют и хорошо понимают под тысячи людей через десятки сообществ.

Visual Studio является, возможно, лучшим IDE, когда-либо разработанным. Это имеет большой компилятор под ним. Но это строго только для Windows.

, Если Вы просто играете, получите GCC - это свободно. Если Вы обеспокоены несколькими платформами, это - GCC. Если Вы говорите серьезная разработка Windows, получаете Visual Studio.

70
задан karoberts 10 December 2009 в 19:40
поделиться

8 ответов

Если в документации API не указано, что это гарантия, то вам не следует полагаться на нее. Поведение может даже измениться от одного выпуска JDK к другому, даже от JDK того же производителя.

Вы можете легко получить набор, а затем просто отсортировать его, не так ли?

47
ответ дан 24 November 2019 в 13:26
поделиться

Карта - это только интерфейс (а не класс), что означает, что базовый класс, реализующий его (а их много), может вести себя по-другому, а контракт для keySet () в API не указывает, что требуется последовательная итерация.

Если вы смотрите на конкретный класс, реализующий Map (HashMap, LinkedHashMap, TreeMap и т. Д.), Вы можете увидеть, как он реализует функцию keySet (), чтобы определить, каким будет поведение, проверив источник, вы d необходимо внимательно изучить алгоритм, чтобы убедиться, что свойство, которое вы ищете, сохраняется (то есть согласованный порядок итераций, когда на карте не было никаких вставок / удалений между итерациями). Источник для HashMap, например, находится здесь (откройте JDK 6): http://www.docjar.com/html/api/java/util/HashMap.java.

9
ответ дан 24 November 2019 в 13:26
поделиться

API для Map не гарантирует какого-либо упорядочивания вообще, даже между несколькими вызовами метода для одного и того же объекта.

На практике я был бы очень удивлен, если бы порядок итераций изменился для нескольких последующих вызовов (при условии, что сама карта не изменилась между ними) - но вы не должны (и согласно API не могут) полагаться на это.

EDIT - если вы хотите полагаться на порядок итераций будучи последовательным, вам нужна SortedMap , которая предоставляет именно эти гарантии.

7
ответ дан 24 November 2019 в 13:26
поделиться

Just for fun, I decided to write some code that you can use to guarantee a random order each time. This is useful so that you can catch cases where you are depending on the order but you should not be. If you want to depend on the order, than as others have said, you should use a SortedMap. If you just use a Map and happen to rely on the order then using the following RandomIterator will catch that. I'd only use it in testing code since it makes use of more memory then not doing it would.

You could also wrap the Map (or the Set) to have them return the RandomeIterator which would then let you use the for-each loop.

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

public class Main
{
    private Main()
    {
    }

    public static void main(final String[] args)
    {
        final Map<String, String> items;

        items = new HashMap<String, String>();
        items.put("A", "1");
        items.put("B", "2");
        items.put("C", "3");
        items.put("D", "4");
        items.put("E", "5");
        items.put("F", "6");
        items.put("G", "7");

        display(items.keySet().iterator());
        System.out.println("---");

        display(items.keySet().iterator());
        System.out.println("---");

        display(new RandomIterator<String>(items.keySet().iterator()));
        System.out.println("---");

        display(new RandomIterator<String>(items.keySet().iterator()));
        System.out.println("---");
    }

    private static <T> void display(final Iterator<T> iterator)
    {
        while(iterator.hasNext())
        {
            final T item;

            item = iterator.next();
            System.out.println(item);
        }
    }
}

class RandomIterator<T>
    implements Iterator<T>
{
    private final Iterator<T> iterator;

    public RandomIterator(final Iterator<T> i)
    {
        final List<T> items;

        items = new ArrayList<T>();

        while(i.hasNext())
        {
            final T item;

            item = i.next();
            items.add(item);
        }

        Collections.shuffle(items);
        iterator = items.iterator();
    }

    public boolean hasNext()
    {
        return (iterator.hasNext());
    }

    public T next()
    {
        return (iterator.next());
    }

    public void remove()
    {
        iterator.remove();
    }
}
5
ответ дан 24 November 2019 в 13:26
поделиться

Hashmap не гарантирует, что порядок карты останется постоянным с течением времени.

3
ответ дан 24 November 2019 в 13:26
поделиться

Не обязательно. Функция keySet карты возвращает Set, а метод итератора этого набора говорит об этом в своей документации:

«Возвращает итератор по элементам в этом наборе. Элементы возвращаются в произвольном порядке (если этот набор не является экземпляром некоторого класса. который обеспечивает гарантию). »

Итак, если вы не используете один из этих классов с гарантией, ее нет.

2
ответ дан 24 November 2019 в 13:26
поделиться

Логически, если в контракте написано «никакой конкретный заказ не гарантирован», и поскольку «заказ, который он выполнил один раз» является конкретным заказом , то ответ будет отрицательным, нельзя полагаться на то, что он выйдет одним и тем же способом дважды.

1
ответ дан 24 November 2019 в 13:26
поделиться

Карта - это интерфейс, и в документации не указано, что порядок должен быть таким же. Значит, на заказ нельзя полагаться. Но если вы управляете реализацией карты, возвращаемой getMap (), то вы можете использовать LinkedHashMap или TreeMap и получать одинаковый порядок ключей / значений все время, когда вы их просматриваете.

2
ответ дан 24 November 2019 в 13:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: