Java 不确定我是否应该搜索或排序我的hashmap
嗨,我有一张有年龄的人的名单,我需要找到那些超过30岁的人, 有没有可能在hashmap中搜索?(请注意,我可能还需要寻找其他年龄段的人,因此为了代码简单起见,我不希望使用两个不同的列表) 简而言之:我的目标是找到一种在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迭代顺序是“不可预测的”(也就是说,如果在以后尝试迭代键时,以确定
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();
//具有年龄的人,其中:(minAgeHashMap 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;
}