【问题标题】:Java: display values based on sorted keys in hashmapJava:根据哈希图中的排序键显示值
【发布时间】:2016-11-13 16:08:04
【问题描述】:

我有一个 HashMap,我已经对类别进行了排序并将其放入一个列表中,即最初的类别是:-A、B、C、D,排序后是 D、C、B、A,我添加了将其添加到列表中。

我想根据类别的排序顺序显示问题,即 显示所有类别的问题:- D 然后显示所有类别的问题:- C 等等。

这是我尝试过的:-

   List<Category> list = Arrays.asList(Category.values());
     List<Question> list1 = new ArrayList<>();
     list1.addAll(questionList);


    Collections.sort(list, new Comparator<Category>() {
        @Override
        public int compare(Category o1, Category o2) {
            return o2.ordinal() - o1.ordinal();

        }
    });
    System.out.println("Categories" +list);
    Map< List<Category>,List<Question>> map = new HashMap<>();

     map.put(list, list1);}}

   boolean ty = list1.containsAll(list1);
    if(ty==true){
  out.println(list1.get(0).getQuestion())  ;}

我希望我的输出是这样的:-

D:你叫什么名字? 你好吗?

C:另一个问题1? 另一个问题2?

B:另一个问题3? 另一个问题4?

【问题讨论】:

  • 看起来您需要LinkedHashMap&lt;Category, List&lt;Question&gt;&gt; 而不是HashMap&lt; List&lt;Category&gt;, List&lt;Question&gt;&gt;。这是因为与LinkedHashMap 不同,HashMap 没有排序,此外,您需要使用单个类别作为键而不是整个类别列表作为单个键,但是,如果您想以特定顺序访问问题,我不确定Map 是否是对数据建模的好方法。
  • 我不明白您为地图选择的键类型。为什么要将类别列表而不是单个类别作为您的关键?
  • 您发布的代码与您描述的目标无关。诚然,您应该用代码发布您的问题,但这应该是一种解决问题的尝试。发布的代码执行以下操作: • 将预定义的Category 常量列表创建为list, • 创建questionList 的副本,作为list1, • 将list 完全按照它已有的顺序排序, • 创建一个奇怪类型的Map, • 将list1 与其自身进行比较, • 如果true==true,则打印list1.get(0).getQuestion()。所以整个代码可以缩短为out.println(questionList.get(0).getQuestion());...

标签: java sorting arraylist collections hashmap


【解决方案1】:

我想根据类别的排序顺序显示问题,即 显示所有问题类别:- D 然后显示所有问题 与类别:- C 等等。

要满足您的需求,问题必须与类别相关。

你有两种做法:

  • 使用比较器(如 @Surace 所做的那样)对最终列表中的所有问题进行排序。
  • 创建地图(问题列表为值,类别为键)

Comparator 更简洁,这是一个好主意,但在您的情况下,它有一个缺点,当您希望在渲染中使用它时,它不会保留与每个问题相关联的类别:

我希望我的输出是这样的:-

D:你叫什么名字?你好吗?

C:另一个问题1?另一个问题2?

B:另一个问题3?另一个问题4?

您可以使用存储在问题中的类别信息来检索信息,但这会迫使您在迭代期间进行相当笨拙的处理,因为类别不是外部信息,而是您必须在另一个对象中搜索的计算信息。

通过创建按类别关联问题的地图,您只需要迭代以呈现信息,并且更一般地,您可以对类别的每次迭代执行任何额外的处理。

这里是代码:

public static void main(String[] args) {

  // create your questions
  List<Question> questionsInput = new ArrayList<>();
  questionsInput.add(new Question("question 1 For A?", Category.A));
  questionsInput.add(new Question("question 2 For A?", Category.A));

  questionsInput.add(new Question("question 1 For A?", Category.B));
  questionsInput.add(new Question("question 2 For A?", Category.B));

  Map<Category, List<Question>> map = associateQuestionByCat(questionsInput);

  // display info
  for (Entry<Category, List<Question>> entry : map.entrySet()) {
      System.out.print("cat " + entry.getKey() + ":");
      for (Question q : entry.getValue()) {
        System.out.print(q.getQuestion());
      }
      System.out.println("");
  }

}

public static Map<Category, List<Question>> associateQuestionByCat(List<Question> questions ) {

  Map<Category, List<Question>> questionsByCategory = new TreeMap<>(Collections.reverseOrder());

  for (Question q : questions) {
    final Category currentCat = q.getCat();
    List<Question> questionsForCurrentCat = questionsByCategory.get(currentCat);
    if (questionsForCurrentCat == null) {
        questionsForCurrentCat = new ArrayList<>();
        questionsByCategory.put(currentCat, questionsForCurrentCat);
    }
    questionsForCurrentCat.add(q);
  }

  return questionsByCategory;
  }
}

【讨论】:

  • 只是一个提示:Category 显然是一个enum,所以你根本不需要实现一个Comparator。您可以只使用new TreeMap&lt;&gt;();,但使用EnumMap 而不是TreeMap 会更高效。
  • @Holger 用户等待以与枚举序数相反的顺序显示类别,而使用 EnumMap,条目按枚举序数的顺序维护。
  • 哦。 OP 希望类别以相反的顺序。这真的很好隐藏......不过,如果你想以相反的顺序排序,只需使用reverseOrder() 而不是实现自己的比较器。然后,每个读者都会立即意识到这个意图。
  • 那个时候,我同意你的观点,因为它使代码更短并且保持可读性。我更新了:)啊,我忘了,比较器来自原始代码,但这不是借口;)
  • 请注意,new TreeMap&lt;&gt;(Collections.reverseOrder()); 需要 Java 8。在 Java 7 中,您必须插入显式类型,即 new TreeMap&lt;&gt;(Collections.&lt;Category&gt;reverseOrder()); 或临时变量,即 Comparator&lt;Category&gt; cmp=Collections.reverseOrder(); … new TreeMap&lt;&gt;(cmp);
【解决方案2】:

我认为这将提供您预期的输出。

Collections.sort(list, new Comparator<Category>() {

      @Override
      public int compare(Category o1, Category o2) {
//       o1.getCategoryName() is A or B or C or D
         return o1.getCategoryName().compareTo(o2.getCategoryName()); 
        }
});

【讨论】:

  • 你得到了吗?如果没有,请告诉我,我会根据您的要求更新我的答案。
  • o1.getQuestion().substring(0,1) 给出问题的第一个字母。我认为在你的情况下是 A,B,C,D。
猜你喜欢
  • 1970-01-01
  • 2018-05-10
  • 2012-03-07
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多