【问题标题】:What to return when printing out Objects using the toString method and a for each loop?使用 toString 方法和 for each 循环打印出 Objects 时返回什么?
【发布时间】:2014-01-17 22:22:40
【问题描述】:

我目前有一个 toString 方法,类似于下面的方法。请忽略对象只是临时命名的。我这样做是为了不混淆每个变量的类型等:

@Override
public String toString() {
    for(Object object : ArrayList) {
        System.out.println("This object is a " + object.getVariableA() + " and a " + object.getVariableB() + ".");
    }
    return null;
}

但是 toString 方法要求我返回一个值。我显然只想返回我正在打印的字符串,尽管如果我在那里放置一个 return 语句,它只会打印一个对象,而不是我正在循环的所有对象。打印所有这些值而不是简单地返回 null 的最佳方法是什么,因为我不希望在所有对象之后打印出来?我还想确保这些对象中的每一个都像现在一样打印在单独的行上,所以请不要建议包含一个没有换行符的长连接字符串的解决方案,因为这不适合这种情况。

提前致谢!

【问题讨论】:

  • toString() 应该返回一个包含对象“描述”的字符串。它不应该打印任何东西。阅读 Object.toString() 的 javadoc。
  • @JBNizet 这是我最初的评论,但后来意识到 OP 只是在展示他们喜欢返回的内容。也就是说......“所以请不要建议包含一个长连接字符串的解决方案”......好吧,那么是的,你做错了

标签: java arraylist foreach tostring object-to-string


【解决方案1】:

toString 不应该输出任何东西。它的工作是返回相关对象的适当字符串表示,而不是在任何地方输出该表示。这超出了它的问题域。

相反,构建并返回一个字符串(可能使用StringBuilder)。

例如,类似:

@Override
public String toString() {
    StringBuilder sb = new StringBuilder(some_appropriate_size);
    for(Object object : ArrayList) {
        sb.append("This object is a ")
          .append(object.getVariableA())
          .append(" and a ")
          .append(object.getVariableB())
          .append(".\n");
    }
    return sb.toString();
}

我还想确保这些对象中的每一个都像现在一样打印在单独的行上,所以请不要建议包含一个长连接字符串的解决方案,因为这不适合这种情况。

上面将数组列表中的项目放在单独的“行”上(通过\n)。但是“一个长连接的字符串”是 唯一 适合 toString 做的事情。如果你想要不同的结果,你必须使用不同的方法,而不是违反toString的约定。

【讨论】:

  • +1 您正在追加内进行字符串连接。 :) 将调用链接到 append 会更有效。
  • @ZouZou:真的。
  • 感谢@T.J.Crowder,这是一个很好的解决方案。尽管目前 StringBuilder 在最后打印的 String 上添加了一个新行,但这是不想要的。如何确保最后一个字符串不以新行“\n”结尾?
  • @edwoollard:有很多方法。例如,您可以在循环之后添加sb.deleteCharAt(sb.length())。或者在最后一个追加中使用".",并有一个用于first追加的变量,该变量最初包含"The object is a ",但随后在第一个循环(追加之后)被设置为"\nThe object is a "。或者有一个标志,boolean first = true;并在循环的开头有if (first) { first = false; } else { sb.append("\n"); }。或者...
【解决方案2】:

您可以创建一个String 并在每次迭代中添加您想要的内容:

@Override
public String toString() {
    String result = "";
    for(Object object : ArrayList) {
        result += "This object is a " + object.getVariableA() + " and a " + object.getVariableB() + ".\n");
    }
    return result;
}

不要忘记添加 "\n" 换行符,以便将每个“部分结果”打印在不同的行中。

【讨论】:

  • s/String/StringBuilder/
【解决方案3】:

您在问题中声明:

我还想确保这些对象中的每一个都像现在一样打印在单独的行上,所以请不要建议包含一个长连接字符串的解决方案,因为这不适合这种情况。

那么你可能不应该使用toString();那不是它的用途。它用于返回作为对象的某种表示形式的单个字符串。它应该从不输出任何东西。

在您的类中添加一个 getter,它返回对象的 List,根据需要输出它们。如果你真的想让类自动打印,添加一个print(OutputStream os) 方法,它采用提供的OutputStream(或者可能是PrintStream)并且会这样做。

【讨论】:

  • 我编辑了我的问题以重新措辞。我确实想返回一个字符串,但我想确保人们理解我希望它以多行返回。我想我可能会用一个冗长的字符串找到解决方案,因为要显示很多内容,因此在我的示例中不实用。
  • 即便如此,听起来您确实不像预期的那样使用toString()。这真的不是为了那个。
  • 我完全满足于使用StringBuilder 并从toString() 方法返回它,所以是的,我正在按照它的预期使用它。这就是为什么我首先在​​ StackOverflow 上提出这个问题。
猜你喜欢
  • 2015-04-26
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 2021-08-18
相关资源
最近更新 更多