简体   繁体   English

从HashMap获取第一个和最后一个元素

[英]Get first and last element from a HashMap

I have the following code and I'd like to get able to get the first and last element from the Map and assign each to a String. 我有以下代码,我希望能够从Map中获取第一个和最后一个元素,并将每个元素分配给一个String。

String result1stElement = null;
String resultLastElement = null;

Map<String, String> result = new HashMap<String, String>();
result = myModel.getSampleResults();

Any ideas. 有任何想法吗。

Thanks in advance. 提前致谢。

First of all, Maps are not ordered so you wont really have a first and last element. 首先,地图没有排序,因此您不会真正拥有第一个和最后一个元素。

However, if you wish to get the first and last element of this anyways you could just get the values and convert this into an array. 但是,如果您仍然希望获取其第一个和最后一个元素,则可以获取值并将其转换为数组。 This isn't really pretty, but it'll work. 这不是很漂亮,但是会起作用。

Map<String, String> result = new HashMap<String, String>();
result = myModel.getSampleResults();
map.values().toArray()[0]; //First result
map.values().toArray()[result.size()-1]; //Last result

Note: This is not tested with a compiler. 注意:未经编译器测试。

First and last element concepts not applicable to Hash-based structures like HashMap and HashSet. 第一个和最后一个元素概念不适用于基于哈希的结构,例如HashMap和HashSet。 Insertion or deletion of key may cause element reordering on-the-fly. 插入或删除密钥可能会导致元素动态重新排序。

I guess your model results is an key-value pairs list, not hash map. 我猜您的模型结果是键值对列表,而不是哈希图。 In this case element ordering is in place. 在这种情况下,元素排序就位。 LinkedHashMap keeps insertion order of elements. LinkedHashMap保持元素的插入顺序。

Replace HashMap to LinkedHashMap (and modify .getSampleResults() ) to return LinkedHashMap and check this question for futher details Java LinkedHashMap get first or last entry . HashMap替换为LinkedHashMap (并修改.getSampleResults() )以返回LinkedHashMap并检查此问题以获取更多详细信息Java LinkedHashMap获得第一个或最后一个条目

There is no such a thing as a first and last element in a HashMap . HashMap没有第一个元素和最后一个元素。 This is the price you have to pay for O(1) lookup: internally the implementation will chuck your entries into a list of buckets in no easily identifiable (but deterministic) order. 这是您必须为O(1)查找付出的代价:在内部,实现将以不容易识别(但确定性)的顺序将您的条目放入存储桶列表中。 This process puts the Hash in HashMap , and in fact the more chaotic it is, the better the performance. 此过程将Hash放入HashMap ,实际上,它越混乱,性能就越好。

You can use a TreeMap if you want a map sorted by the natural order of its keys (or a custom comparator) or you can have a LinkedHashMap if you want the elements to be arranged in the order of insertion. 如果希望按其键的自然顺序(或自定义比较器)对地图进行排序,则可以使用TreeMap如果希望按插入顺序排列元素,则可以使用LinkedHashMap

Ps: even if you choose a Map implementation that maintains some kind of order, calling toArray() just to get the first and last elements is a massive overkill, I wouldn't do it. 附言:即使您选择维护某种顺序的Map实现,仅仅为了获取第一个和最后一个元素而调用toArray()也是一个巨大的矫kill过正,我不会这样做。 TreeMap has firstEntry() and lastEntry() methods, and even with LinkedHashMap , it's a lot cheaper to just manually iterate across the elements and keep the first and last one instead of allocating a potentially huge array. TreeMap具有firstEntry()lastEntry()方法,即使使用LinkedHashMap ,只需手动遍历元素并保留第一个和最后一个元素,而不是分配可能的大数组,也要便宜得多。

HashMap has no such thing as order. HashMap没有命令之类的东西。 From HashMap javadoc : 从HashMap javadoc

This class makes no guarantees as to the order of the map; 此类无法保证地图的顺序。 in particular, it does not guarantee that the order will remain constant over time. 特别是,它不能保证顺序会随着时间的推移保持恒定。

You'll have to use LinkedHashMap . 您必须使用LinkedHashMap Take a look at entrySet() method and this question+answer 看看entrySet()方法和这个问题+答案

"toArray" method of Set interface can be used. 可以使用Set接口的“ toArray”方法。

But iterating over the entries in the entry set and getting the first and last entry is a better approach. 但是,迭代条目集中的条目并获取第一个和最后一个条目是一种更好的方法。

This example might be helpful: 该示例可能会有所帮助:

public static void main(final String[] args) {
        final Map<Integer,String> orderMap = new LinkedHashMap<Integer,String>();
        orderMap.put(6, "Six");
        orderMap.put(7, "Seven");
        orderMap.put(3, "Three");
        orderMap.put(100, "Hundered");
        orderMap.put(10, "Ten");

        final Set<Entry<Integer, String>> mapValues = orderMap.entrySet();
        final int maplength = mapValues.size();
        final Entry<Integer,String>[] test = new Entry[maplength];
        mapValues.toArray(test);

        System.out.print("First Key:"+test[0].getKey());
        System.out.println(" First Value:"+test[0].getValue());

        System.out.print("Last Key:"+test[maplength-1].getKey());
        System.out.println(" Last Value:"+test[maplength-1].getValue());
    }

// the output geneated is :
First Key:6 First Value:Six
Last Key:10 Last Value:Ten

Your comment to @Nikolay's answer shows an important detail of your question that was hidden until now. 您对@Nikolay答案的评论显示了到目前为止一直隐藏的问题的重要细节。

So, you want to test a method which uses a HashMap structure for refering to some added objects and you want to test, if this method delivers some ordering in this structure? 因此,您想测试一种使用HashMap结构引用一些添加对象的方法,并且是否要测试该方法是否在该结构中提供了某种顺序? First added object shall remain at a "first position", last added object at a "last position"? 第一个添加的对象应保持在“第一个位置”,最后一个添加的对象应处于“最后一个位置”?

As the other answers already show, there is no way without refactoring that method. 正如其他答案已经表明的那样,没有方法就无法重构。 HashMap doesn't deliver any meaningful ordering at all and if that method should deliver some ordering, it is simply broken - implementation is faulty. HashMap根本不提供任何有意义的排序,并且如果该方法应该提供某种排序,那么它就被破坏了-实现存在错误。

Of course, you can write a unit test using the algorithm provided by @Sander. 当然,您可以使用@Sander提供的算法编写单元测试。 This test will fail most of the time. 该测试在大多数情况下都会失败。 And this again shows the fact, that the tested method has to be refactured like @Nikolay showed in his answer, for instance. 这再次表明了这样一个事实,例如,必须像在其答案中显示的@Nikolay一样重新构造经过测试的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM