【问题标题】:Sorting a HashMap based on an index in an ArrayList using a generic function使用泛型函数根据 ArrayList 中的索引对 HashMap 进行排序
【发布时间】:2015-02-03 00:41:20
【问题描述】:

所以我正在尝试对包含人名(键)及其年龄和身高(以厘米为单位)的 HashMap 进行排序。 HashMap 是这样设置的:

    Map<String, List<Integer>> s = new HashMap<>();
    List<Integer> l1, l2, l3, l4;
    l1 = new ArrayList<>();
    l2 = new ArrayList();
    l3 = new ArrayList();
    l4 = new ArrayList();
    l1.add(22); l1.add(177);  //age then height
    l2.add(45); l2.add(162);
    l3.add(19); l3.add(182);
    l4.add(38); l4.add(174); 
    s.put("John", l1);
    s.put("Eric", l2);
    s.put("Darren", l3);
    s.put("Carter", l4);

然后我想使用通用函数按人的身高对地图进行排序。

这是我尝试过的:

static <K, V extends List<? extends Comparable<? super V>>> Map<K, V> specialSort(Map<K, V> map) {
    Map<K, V> result = new LinkedHashMap<>();
    Stream<Entry<K, V>> st = map.entrySet().stream();
    st.sorted(Comparator.comparing(e -> e.getValue().get(0))).
            forEach(e -> result.put(e.getKey(), e.getValue()));

    return result;
}

但是我得到了这个错误:

incompatible types: inferred type does not conform to upper bound(s)
inferred: CAP#1
upper bound(s): Comparable<? super CAP#1>,V,Object
where V,K are type-variables:
V extends List<? extends Comparable<? super V>> declared in method <K,V>specialSort(Map<K,V>)
K extends Object declared in method <K,V>specialSort(Map<K,V>)
where CAP#1 is a fresh type-variable:
CAP#1 extends Comparable<? super V> from capture of ? extends Comparable<? super V>

我使用的基本函数来自这个线程:https://stackoverflow.com/a/2581754

这是函数:

public static <K, V extends Comparable<? super V>> Map<K, V> 
sortByValue( Map<K, V> map )
{
   Map<K,V> result = new LinkedHashMap<>();
   Stream <Entry<K,V>> st = map.entrySet().stream();

   st.sorted(Comparator.comparing(e -> e.getValue()))
        .forEach(e ->result.put(e.getKey(),e.getValue()));

   return result;
}

我一直试图让它工作大约一个半小时,我几乎已经放弃了。请帮忙!

【问题讨论】:

  • 我看到这一行并认为拥有一个具有高度和年龄字段的对象会容易得多:l1.add(22); l1.add(177); //年龄然后身高
  • 你真的必须将年龄和身高放入一个普通的 ArrayList 中吗?这不是完全面向对象的。
  • 所以我的第一个问题是为什么需要按高度排序?就像您是否尝试为最大高度为 in 或最终情况做一个打印语句。可能有更好的方法,然后必须对列表进行排序
  • 我忘记了名字是什么,但这看起来真的像“对象避免”反模式,或者类似的东西。为什么没有一个Person 类,其中包含名称、年龄和身高,以及一个可以按身高排序的List&lt;Person&gt;。如果您确实需要按名称查找它们,可以使用单独的Map&lt;String, Person&gt;。你可以修复你的类型错误,但我认为你的方法是错误的。
  • 我主要用它来学习泛型、映射和 lambda。我目前正在上计算机科学的第一学期,并且已经学习了 java 语法的基础知识,但是在空闲时间我一直在尝试学习更多东西,因为我太不耐烦了,无法等待课程到达那里。通常我所做的是我想出一个问题(在这种情况下按人的身高对地图进行排序)来解决。当我遇到问题时,我会尝试找到一个示例并从中学习,但我无法在这里找到我想要的东西,这就是我制作这个的原因。不过,我可能应该创建一个 Person OOP 类。

标签: java generics arraylist hashmap


【解决方案1】:

好的,就像你的问题在 cmets 中提到的那样,它并不是真正的面向对象的方法
但是用泛型和 lambda 练习就很好。

当您还声明列表类型时,它会起作用。

public static <K, V extends Comparable<? super V>> Map<K, List<V>> sortByValue( Map<K, List<V>> map ) {
   Map<K,List<V>> result = new LinkedHashMap<>();
   Stream <Entry<K,List<V>>> st = map.entrySet().stream();

   st.sorted(Comparator.comparing(e -> e.getValue().get(1)))
     .forEach(e -> result.put(e.getKey(), e.getValue()));

   return result;
}    

或者,您可以通过这种方式使用 sorted 方法:

st.sorted((e1,e2)->{return e1.getValue().get(1).compareTo(e2.getValue().get(1));})
  .forEach(e -> result.put(e.getKey(), e.getValue()));

并检查结果:

result.forEach( (name, list)-> System.out.println(""+name+":" + list.get(1).toString()));

【讨论】:

    猜你喜欢
    • 2012-09-28
    • 1970-01-01
    • 2015-04-22
    • 2013-11-21
    • 1970-01-01
    • 2015-03-31
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多