【问题标题】:Equal spacing in Enumerations?枚举中的等间距?
【发布时间】:2026-02-09 12:05:02
【问题描述】:

我正在学习 Java 课程,该部分是关于枚举的。我的枚举中有这个:

public enum tuna {
 Camaro("Orange", "1968"),
 Silverado("Red","1996"),
 Sierra("Black","2007"),
 Equinox("Silver","2011");

  private final String color;
  private final String year;


tuna(String carColor, String age){
    color = carColor;
    year = age;

 }
public String getColor(){
    return color;
 }

public String getYear(){
    return year;
 }
}

这在我的 Java 类中打印出来:

for(tuna cars: tuna.values()){
    System.out.printf("%s\t\t%s\t\t%s\n", cars, cars.getColor(), cars.getYear()

打印出来的:

看到 Silverado 的“Red”和“1996”在右边是怎么回事(因为“Silverado”比其他词长)? 那么我该如何解决它,以便长词的详细信息与其他内容等距?

附:如果我将“Silverado”缩短为“Silver”,这很正常:

【问题讨论】:

  • 只是一个样式点 - 类应始终以大写字母开头并遵循 CamelCase 格式。
  • 在您最喜欢的百科全书中查找“制表符”的概念。

标签: java enums enumeration


【解决方案1】:

我建议不要使用制表符,而是使用字符串格式,即使用 System.out.format(...) 并通过获取最长名称的长度来计算每个格式说明符的长度。然后动态构建格式字符串。

例子:

//that's a shortcut, you'd have to calculate the max
int maxlength = tuna.Silverado.name().length();

for( tuna t : tuna.values() ) {
  System.out.format( "%-" + maxlength + "s   %-10s %4s\n", t.name(), t.getColor(), t.getYear() );
}

输出:

Camaro      Orange     1968
Silverado   Red        1996
Sierra      Black      2007
Equinox     Silver     2011

【讨论】:

    【解决方案2】:

    制表符 (\t) 将光标向前移动,直到它到达可被制表符大小整除的位置:如果大小为例如8,它将变为 0、8、16、24 等。由于“Silverado”的长度为 9 个字符,这将导致值 16,而不是 8。

    您必须自己进行制表符:根据前面字符串的长度添加空格,而不是使用\t

    如果您想要最简单的解决方案,请为每个字段确定一个合适的最大长度,并据此计算您的制表符,可选择截断比这更长的字符串。

    对于动态解决方案,您必须根据可用的项目检查所需的最大长度。这可以让您获得所需的最小间距。

    【讨论】:

      【解决方案3】:

      根本不要使用标签。而是通过在 %s 字段中使用 int 常量来更好地使用 printf 以最大限度地提高其灵活性。即 %10s 或 %-10s 或任何最适合该列的 int 常量。

      【讨论】:

        【解决方案4】:

        这与枚举无关。唯一重要的是这一行:

        System.out.printf("%s\t%s\t\t%s\n", cars, cars.getColor(), cars.getYear()
        

        您需要的是字符串填充。您可以使用System.out.format 方法,它允许以%5s 的形式填充,这意味着它将向左填充字符串最多5 个空格。

        因此您可以计算字段的最大长度并动态构建格式字符串:

            int maxCars = 0;
            int maxColor = 0;
            int maxYear = 0;
        
            for(tuna cars: tuna.values()) {
                maxCars = Math.max(maxCars, cars.toString().length());
                maxColor = Math.max(maxColor, cars.getColor().length());
                maxYear = Math.max(maxYear, cars.getYear().length());
            }
        
            String formatStr = "%"+(maxCars+5)+"s%"+(maxColor+5)+"s%"+(maxYear+5)+"s\n";
        
            for(tuna cars: tuna.values())
                System.out.format(formatStr, cars, cars.getColor(), cars.getYear());
        

        输出是:

                Camaro     Orange     1968
             Silverado        Red     1996
                Sierra      Black     2007
               Equinox     Silver     2011
        

        【讨论】:

          【解决方案5】:

          这是一个制表符间距问题 - 如果您在文本编辑器中以这种方式使用制表符,您会得到相同的结果。对于最大/最小长度相差 > 4 个字符的变量(例如第一列),插入 2 个制表符,而不是像这样:

          for(tuna cars: tuna.values()){
              if (cars.getColor().length() > 5)
                  System.out.printf("%s\t%s\t\t%s\n", cars, cars.getColor(), cars.getYear())
              else
                  System.out.printf("%s\t\t%s\t\t%s\n", cars, cars.getColor(), cars.getYear())
          

          更新已更正为仅输出两个颜色不够长的选项卡。

          【讨论】:

          • 标签仍然不可靠。一个更好的解决方案是使用 %s 字段中的数字常量来最大限度地利用 printf。
          • 好吧,在 Silverado 之后我确实有两个标签。如果我将您的代码复制/粘贴到我的代码中,看看它是否会修复它,它看起来像这样:i.imgur.com/B5LkY.png
          • 为什么标签不可靠?如果使用得当,它们是完全可预测的,用于像这样缩进我们的输入!与使用空格相比,所需的逻辑更少。