【问题标题】:Pretty printing table format of hashmap javahashmap java的漂亮打印表格式
【发布时间】:2020-10-26 14:23:30
【问题描述】:

假设我们有一个键和值的 HashMap,其中键是整数,值是列表,然后我使用 hashMap 构造一个 treeMap 以将其排序:

Map<Integer, List<Boolean>> map = new HashMap<>();
Map<Integer, List<Boolean>> orderedMap = new TreeMap<>(map);

如果我这样做

map.entrySet().forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue())

它在每一行之后吐出每个键及其值。这是我要做的事情,但我认为打印出某些行 x 列更容易。也许可能在移动到下一个之前每行打印 10 个键:值,或者最好在第一列中按顺序打印出 10 个键:值,然后下一列打印下一个 10,依此类推,直到它到达末尾(最后一列不必正好是 10),但我不知道如何达到这个目标

想要的样本输出:

entry1  entry11 ...
entry2  entry12
entry3  entry13
entry4  entry14
entry5  entry15
entry6  .
entry7  .
...     .
entry10 entry20

【问题讨论】:

  • 地图中的每个条目将在地图值列表中具有完全相同数量的元素 - List&lt;Boolean&gt;?此外,如果您还可以提及您正在考虑的示例输出,那就太好了。
  • 是的,每个 entry.getValue() 将在 List 中具有相同数量的元素
  • 这里entry1entry2等是java.util.Map.Entry实例?
  • entry1 只是我说 key1 = value1 其中 key = Integer 和 value = list 的一种方式
  • 打印输入顺序重要吗? HashMap 不保留任何顺序。

标签: java java-8 hashmap pretty-print


【解决方案1】:

如果您只是出于调试/日志记录的目的,那么这里有一个简单的方法,它按列而不是按行打印条目,并且不会多次迭代您的地图。

这里maxCols 是您在打印时希望拥有的列数。

    public static void main(String[] args) {
        Map<Integer, List<Boolean>> map = new HashMap<>();

        map.put(1, Arrays.asList(true, false, false));
        map.put(2, Arrays.asList(false, false, false));
        map.put(3, Arrays.asList(true, true, false));
        map.put(4, Arrays.asList(true, false, true));
        map.put(5, Arrays.asList(false, true, true));
        map.put(6, Arrays.asList(true, false, false));
        map.put(7, Arrays.asList(false, false, false));
        map.put(8, Arrays.asList(true, true, false));
        map.put(9, Arrays.asList(true, false, true));
        map.put(10, Arrays.asList(false, true, true));

        int counter = 1;
        int maxCols = 5;
        for (Map.Entry<Integer, List<Boolean>> entry : map.entrySet()) {
            System.out.printf("%s ", entry);
            counter++;

            if (counter == maxCols) {
                System.out.println();
                counter = 1;
            }
        }
    }

【讨论】:

    【解决方案2】:

    您可能希望使用两个嵌套循环(一个用于行,一个用于列)和Iterator&lt;Entry&lt;Integer, List&lt;Boolean&gt;&gt;&gt; 进行类似的操作,只要您无法从基于其索引的映射中获取条目,就像使用 @ 一样987654322@.

    // define the row size and the Iterator
    int rows = 10; 
    Iterator<Map.Entry<Integer, List<Boolean>>> iterator = map.entrySet().iterator();
    
    for (int i=0; i<rows; i++) {                                           // for each row
        for (int j = 0; j < map.size(); j += rows) {                       // .. for each column
            if (iterator.hasNext()) {                                      // .. if there is a next value 
                Map.Entry<Integer, List<Boolean>> entry = iterator.next(); // .... get it
                System.out.print(entry);                                   // .... print the line
            } else break;                                                  // .... or else break the loop
            System.out.print(" \t");                                       // .. and print the tabulator
        }
        System.out.println();                                              // move to the next line (row)
    }
    

    注意printprintln 的使用位置。这是 38 个条目的示例输出:

    0=[false, true]     1=[true, false]     2=[false, true]     3=[true, false]     
    4=[false, true]     5=[true, false]     6=[false, true]     7=[true, false]     
    8=[false, true]     9=[true, false]     10=[false, true]    11=[true, false]    
    12=[false, true]    13=[true, false]    14=[false, true]    15=[true, false]    
    16=[false, true]    17=[true, false]    18=[false, true]    19=[true, false]    
    20=[false, true]    21=[true, false]    22=[false, true]    23=[true, false]    
    24=[false, true]    25=[true, false]    26=[false, true]    27=[true, false]    
    28=[false, true]    29=[true, false]    30=[false, true]    31=[true, false]    
    32=[false, true]    33=[true, false]    34=[false, true]    35=[true, false]    
    36=[false, true]    37=[true, false]    
    

    免责声明:该代码要求进行大量改进,即当输出出现不规则长度时调整选项卡等。

    【讨论】:

    • 我试过了,但它只是将它们打印在 1 列中,中间有一个空行
    【解决方案3】:

    我会将条目视为一个列表,并用两个正常循环遍历它。这里是一个伪代码:

    List<HashMap.Entry> entries = ...;
    for (int i = 0; i < entries.size()/10; i++) {
      for (int j = i; j < entries.size(); j+=10) {
        HashMap.Entry entry = map.getEntry(j);
        System.out.print(entry + '\t');
      }
      System.out.println();
    }
    

    或者,您可以创建一个包含 10 行的 StringBuffer 数组,并在遍历时将输出附加到正确的行。然后打印所有行。在打印之前将输出存储在二维数组中也是一个有效的选项,如果您想确保列中的所有条目都具有适当数量的尾随空格/制表符,这可能是最好的选择。

    【讨论】:

      猜你喜欢
      • 2011-05-06
      • 1970-01-01
      • 2011-01-07
      • 2011-03-21
      • 2012-03-31
      • 2013-01-20
      • 1970-01-01
      • 2011-05-05
      相关资源
      最近更新 更多