Доступ к последней записи на карте - PullRequest
52 голосов
/ 20 августа 2010

Как переместить определенную запись HashMap в последнюю позицию?

Например, у меня есть значения HashMap, подобные этому:

HashMap<String,Integer> map = new HashMap<String,Integer>();

map= {Not-Specified 1, test 2, testtest 3};

«Не указано» может прийти в любую позицию.это может прийти первым или в середине карты.Но я хочу переместить «Не указано» в последнюю позицию.

Как я могу это сделать?заранее спасибо.

Ответы [ 7 ]

145 голосов
/ 23 августа 2010

Чтобы ответить на ваш вопрос в одном предложении:

По умолчанию у Карт нет последней записи, это не является частью их контракта.


И примечание: рекомендуется кодировать интерфейсы, а не классы реализации (см. Эффективная Java от Джошуа Блоха , глава 8, пункт 52: Ссылки на объекты по их интерфейсам ).

Итак, ваша декларация должна гласить:

Map<String,Integer> map = new HashMap<String,Integer>();

(Все карты имеют общий контракт, поэтому клиенту не нужно знать, что это за карта, если он не указывает подчиненный интерфейс с расширенным контрактом).


Возможные решения

Сортированные карты:

Существует подчиненный интерфейс SortedMap , который расширяет интерфейс карты с помощью методов поиска на основе порядка, и имеет подчиненный интерфейс NavigableMap , который расширяет его еще больше. Стандартная реализация этого интерфейса, TreeMap , позволяет сортировать записи либо путем естественного упорядочения (если они реализуют интерфейс Comparable ), либо с помощью прилагаемого Comparator .

Вы можете получить доступ к последней записи с помощью метода lastEntry :

NavigableMap<String,Integer> map = new TreeMap<String, Integer>();
// add some entries
Entry<String, Integer> lastEntry = map.lastEntry();

Связанные карты:

Существует также специальный случай LinkedHashMap , реализация HashMap, в которой хранится порядок вставки ключей. Однако нет интерфейса для резервного копирования этой функциональности, и нет прямого доступа к последнему ключу. Вы можете сделать это только с помощью таких хитростей, как использование списка между:

Map<String,String> map = new LinkedHashMap<String, Integer>();
// add some entries
List<Entry<String,Integer>> entryList =
    new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Entry<String, Integer> lastEntry =
    entryList.get(entryList.size()-1);

Правильное решение:

Поскольку вы не управляете порядком вставки, вам следует использовать интерфейс NavigableMap, т. Е. Вы бы написали компаратор, который помещает запись Not-Specified последней.

Вот пример:

final NavigableMap<String,Integer> map = 
        new TreeMap<String, Integer>(new Comparator<String>() {
    public int compare(final String o1, final String o2) {
        int result;
        if("Not-Specified".equals(o1)) {
            result=1;
        } else if("Not-Specified".equals(o2)) {
            result=-1;
        } else {
            result =o1.compareTo(o2);
        }
        return result;
    }

});
map.put("test", Integer.valueOf(2));
map.put("Not-Specified", Integer.valueOf(1));
map.put("testtest", Integer.valueOf(3));
final Entry<String, Integer> lastEntry = map.lastEntry();
System.out.println("Last key: "+lastEntry.getKey()
         + ", last value: "+lastEntry.getValue());

Выход:

Последний ключ: не указано, последнее значение: 1

Решение с использованием HashMap:

Если вы должны полагаться на HashMaps, все еще есть решение, использующее a) модифицированную версию вышеуказанного компаратора, b) List , инициализированный с помощью entrySet и c карты ) вспомогательный метод Collections.sort () :

    final Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("test", Integer.valueOf(2));
    map.put("Not-Specified", Integer.valueOf(1));
    map.put("testtest", Integer.valueOf(3));

    final List<Entry<String, Integer>> entries =
        new ArrayList<Entry<String, Integer>>(map.entrySet());
    Collections.sort(entries, new Comparator<Entry<String, Integer>>(){

        public int compareKeys(final String o1, final String o2){
            int result;
            if("Not-Specified".equals(o1)){
                result = 1;
            } else if("Not-Specified".equals(o2)){
                result = -1;
            } else{
                result = o1.compareTo(o2);
            }
            return result;
        }

        @Override
        public int compare(final Entry<String, Integer> o1,
            final Entry<String, Integer> o2){
            return this.compareKeys(o1.getKey(), o2.getKey());
        }

    });

    final Entry<String, Integer> lastEntry =
        entries.get(entries.size() - 1);
    System.out.println("Last key: " + lastEntry.getKey() + ", last value: "
        + lastEntry.getValue());

}

Выход:

Последний ключ: не указано, последнее значение: 1

17 голосов
/ 21 августа 2010

HashMap не имеет "последней позиции" , поскольку она не отсортирована.

Вы можете использовать другие Map, которые реализуют java.util.SortedMap, наиболее популярным из них является TreeMap.

5 голосов
/ 28 августа 2010

A SortedMap является логическим / лучшим выбором, однако другой вариант заключается в использовании LinkedHashMap, который поддерживает два режима заказа, последний добавленный идет последним, а самый последний доступ - последним.См. Javadocs для более подробной информации.

1 голос
/ 29 августа 2010
Перемещение

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

0 голосов
/ 01 мая 2019
Find missing all elements from array
        int[] array = {3,5,7,8,2,1,32,5,7,9,30,5};
        TreeMap<Integer, Integer> map = new TreeMap<>();
        for(int i=0;i<array.length;i++) {
            map.put(array[i], 1);
        }
        int maxSize = map.lastKey();
        for(int j=0;j<maxSize;j++) {
            if(null == map.get(j))
                System.out.println("Missing `enter code here`No:"+j);
        }
0 голосов
/ 28 февраля 2019

В таком случае обычно используется последний использованный ключ, поэтому его можно использовать для доступа к последнему значению (вставленному с одним):

class PostIndexData {
    String _office_name;
    Boolean _isGov;
    public PostIndexData(String name, Boolean gov) {
        _office_name = name;
        _isGov = gov;
    }
}
//-----------------------
class KgpData {
    String _postIndex;
    PostIndexData _postIndexData;
    public KgpData(String postIndex, PostIndexData postIndexData) {
        _postIndex = postIndex;
        _postIndexData = postIndexData;;
    }
}

public class Office2ASMPro {
    private HashMap<String,PostIndexData> _postIndexMap = new HashMap<>();
    private HashMap<String,KgpData> _kgpMap = new HashMap<>();
...
private void addOffice(String kgp, String postIndex, String officeName, Boolean gov) {
            if (_postIndexMap.get(postIndex) == null) {
                _postIndexMap.put(postIndex, new PostIndexData(officeName, gov));
            }
            _kgpMap.put( kgp, new KgpData(postIndex, _postIndexMap.get(postIndex)) );
        }
0 голосов
/ 04 февраля 2017

При использовании чисел в качестве ключа, я полагаю, вы также можете попробовать это:

        Map<Long, String> map = new HashMap<>();
        map.put(4L, "The First");
        map.put(6L, "The Second");
        map.put(11L, "The Last");

        long lastKey = 0;
        //you entered Map<Long, String> entry
        for (Map.Entry<Long, String> entry : map.entrySet()) {
            lastKey = entry.getKey();
        }
        System.out.println(lastKey); // 11
...