Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不确定我是否应该搜索或排序我的hashmap_Java_Search_Sorting_Hashmap - Fatal编程技术网

Java 不确定我是否应该搜索或排序我的hashmap

Java 不确定我是否应该搜索或排序我的hashmap,java,search,sorting,hashmap,Java,Search,Sorting,Hashmap,嗨,我有一张有年龄的人的名单,我需要找到那些超过30岁的人, 有没有可能在hashmap中搜索?(请注意,我可能还需要寻找其他年龄段的人,因此为了代码简单起见,我不希望使用两个不同的列表) 简而言之:我的目标是找到一种在HashMap中搜索具有特定值的元素的方法 样本列表为 element1 40 element2 4 element3 66 element4 5 我想找到那些值大于40的和那些值大于或等于66的。HashMap迭代顺序是“不可预测的”(也就是说,如果在以后尝试迭代键时,以确定

嗨,我有一张有年龄的人的名单,我需要找到那些超过30岁的人, 有没有可能在hashmap中搜索?(请注意,我可能还需要寻找其他年龄段的人,因此为了代码简单起见,我不希望使用两个不同的列表)

简而言之:我的目标是找到一种在HashMap中搜索具有特定值的元素的方法

样本列表为

element1 40
element2 4
element3 66
element4 5

我想找到那些值大于40的和那些值大于或等于66的。

HashMap
迭代顺序是“不可预测的”(也就是说,如果在以后尝试迭代键时,以确定的顺序排序并插入键,则顺序是不一样的)


改用
LinkedHashMap

好问题。。。不幸的是,地图需要一个非常特定的键。你上面的解决方案是唯一真正做到这一点的方法


或者,您可以维护两个列表,并将超过30的列表存储到第二个列表。

您无法对
哈希映射进行排序,因为它没有顺序。如果您想要一个有序的
HashMap
,请使用
LinkedHashMap

,我建议您使用(作为TreeSet实现)

这个实现是一个相当快的-O(log(N)),而如果您实现基于列表的索引,则是O(N)

编辑。例如:

class PersonsAgeIndex {

    private NavigableMap<Integer, List<Person>> ageToPersons = 
                                    new TreeMap<Integer, List<Person>>();

    public void addPerson( Person p ) {
        List<Person> personsWithSameAge = this.ageToPersons.get( p.age );

        if ( personsWithSameAge == null ) {
            personsWithSameAge = new LinkedList<Person>();
            this.ageToPersons.put( p.age, personsWithSameAge );
        }

        personsWithSameAge.add( p );
    }

    public List<Person> personsWithAgeLessThan( int age ) {
        List<Person> persons = new LinkedList<Person>();

        // persons with less age
        for (List<Person> tmp : this.ageToPersons.headMap( age ).values()) {
            persons.addAll( tmp );
        }

        return persons;
    }

    public List<Person> personsWithAgeInInterval( int minAge, int maxAge ) {
        List<Person> persons = new LinkedList<Person>();

        // persons with age, which: (minAge <= age <= maxAge)
        for (List<Person> tmp : this.ageToPersons.subMap( minAge, true, maxAge, true ).values()) {
            persons.addAll( tmp );
        }

        return persons;
    }

}

class Person {
    public final int age;

    public Person(int age) {
        this.age = age;
    }
}
classpersonsageindex{
private NavigableMap ageToPersons=
新树映射();
公众人士(p人){
List personswithameage=this.ageToPersons.get(p.age);
if(personwithsameage==null){
PersonWithSameage=newLinkedList();
this.ageToPersons.put(p.age,personswithameage);
}
增加(p)名;
}
无年龄(国际年龄)的公众名单人员{
列表人员=新建LinkedList();
//年龄较小的人
对于(列出tmp:this.ageToPersons.headMap(age.values()){
人员。addAll(tmp);
}
返回人员;
}
在Interval(int minAge、int maxAge)中使用Age的公共列表人员{
列表人员=新建LinkedList();
//具有年龄的人,其中:(minAge
HashMap hmap=new HashMap();
SortedSet keys=新树集(hmap.keySet());
这将为您提供一个排序集,您可以将其作为一个子集

键。子集(从,到),例如键。子集(30100)

您将拥有一套包含所有必需元素的设备。

尝试以下方法:

 private List<Person> getPeople(Map<?, Person> peopleMap, int filterAge) {
    List<Person> returnList = new ArrayList<Person>(peopleMap.values().size());
    for (Person p : peopleMap.values()) {
        if (p.getAge() > filterAge)
        returnList.add(p);
    }
    return returnList;
    }

private List getPeople(map)您使用的是ArrayList还是HashMap?您是在尝试搜索、选择还是排序?您所说的“不工作”是什么意思?您显示的代码应该可以工作。一旦您对列表进行了排序,您就可以使用二进制搜索来查找特定的年龄。但是,如果您尝试将这些人重新添加到HashMap中,则顺序将丢失。如果您只需执行一次,@assylias的评论是正确的——这样做的工作量要小得多(而且更直接)简单地遍历列表并选择超过30个的…我假设这是我的答案中问题的意图(在对数组进行排序之前,而不是出于其他原因放入映射)…因此,如果您确实想要使用地图,那么可以考虑使用LinkedHashMap来维持插入顺序…人脉地图的结构是什么?在您的场景2中,人不能有相同的年龄。对downvote的评论?看起来像是幼稚的愤怒,不是吗,opc0de;)我没有投反对票,但你的答案有什么帮助?只是将映射实现从hashmap更改为linkedhashmap不会解决问题。是的,这样做是因为他可以在评论问题时对其进行排序。我并不同意这种方法,但它会起作用:)@stemm,谢谢你的回答,但我建议不要使用不同的列表,因为我有一些其他要求,我不应该将它们放在两个不同的列表中,例如,我可能需要超过10个,在这种情况下,我需要为这些项建立另一个列表。@Eme Emertana,NavigableSet接口中有很多方法,m方法
tailMap
将解决“年龄大于10岁”的情况。方法
subMap
将解决其他情况。此外,您可以独立于总人员列表使用PersonIndex。这是
索引的常见做法
usage@stemm,这是否意味着我应该使用NavigableMap或TreeSet?@Eme Emertana,我添加了方法
 personsWithAgeInInterval
涵盖了您的所有情况。@Eme Emertana,使您的类依赖于接口(例如
NavigableSet
)比依赖于特定实现(
TreeSet
)要好-这是灵活设计的概念之一。看看我上面的代码。例如,如果你想使
PersonsAgeIndex
面向并发,你所要做的就是-只需将
new TreeMap
更改为
new ConcurrentSkipListMap
。另外,仔细阅读javadoc,这里有很多有用的信息
 private List<Person> getPeople(Map<?, Person> peopleMap, int filterAge) {
    List<Person> returnList = new ArrayList<Person>(peopleMap.values().size());
    for (Person p : peopleMap.values()) {
        if (p.getAge() > filterAge)
        returnList.add(p);
    }
    return returnList;
    }