【问题标题】:Unused variable in a loop循环中未使用的变量
【发布时间】:2013-10-21 04:04:47
【问题描述】:

我需要根据参数列表构建模式字符串。如果参数是"foo", "bar", "data",那么模式应该是:"?, ?, ?"

我的代码是:

List<String> args;
...
for(String s : args) {
  pattern += "?,";
}
pattern = pattern.substring(0, pattern.length()-1);

它工作正常,唯一担心的是,s 没有使用,看起来代码有点脏。

对此有何改进?

我希望是这样的:

for(args.size()) {
    ...
}

但显然没有..

【问题讨论】:

  • 题外话:如果您添加,? 而不是?, 并将pattern.substring(0, pattern.length()-1) 更改为pattern.substring(1),它可能会更快更容易阅读

标签: java loops foreach


【解决方案1】:

您可以在条件下使用 for loop 类:

for (int i = 0, s < args.size(); i++)

在这种情况下,i 被用作计数变量。

除此之外,没有任何需要改进的地方,尽管不需要改进。

【讨论】:

  • 也许没有这样的“改进”可用,但 eclipse 抱怨未使用的变量,这让我有点恼火。这种情况下我加@SuppressWarnings("unused")可以吗?
【解决方案2】:

我通常用 Haskell / Python 风格来做这件事——用“_”命名。这样,很明显变量是故意不使用的:

int n = 0;
for (final Object _ : iterable) { ++n; }

不过,IntelliJ 仍然在抱怨 :)

【讨论】:

    【解决方案3】:

    另一个选择是使用 Java Stream 的 api。挺好看的。

    String output = args
                .stream()
                .map( string -> "?" ) // transform each string into a ?
                .collect( Collectors.joining( "," ) ); // collect and join on ,
    

    【讨论】:

    • 哇,我刚刚注意到这是 6 岁...为什么它会出现在我的提要上大声笑
    【解决方案4】:

    为什么不使用 for (int i = 0; i < args.size(); i++) { ... }

    如果你想利用你迭代的任何内容,你可以使用 for each 块。例如,如果您知道要使用 args 中存在的每个字符串值,则使用 for (String s : args)。看起来像这里,你不需要实际的字符串。

    【讨论】:

    • 也许我在这里分了头发,对我来说这个经典的 for 循环不像 for-each 循环那样简洁。
    【解决方案5】:

    如果您身边有番石榴,您可以尝试将JoinerCollections.nCopies 结合使用:

    Joiner.on(", ").join(Collections.nCopies(args.size(), "?"));
    

    【讨论】:

    • 谢谢,非常强大,虽然目前我似乎无法将Guava 介绍给我的项目。
    【解决方案6】:

    您正在寻找的是一个称为“加入”的概念。在像 Groovy 这样更强大的语言中,它在标准库中可用,您可以编写例如 args.join(',') 来获得您想要的东西。使用 Java,您可以从 Commons Lang 中获得与 StringUtils.join(args, ",") 类似的效果(每个 Java 项目都应该包含的库)。

    更新:我显然错过了原始答案的重要部分。字符串列表需要先变成问号。 Commons Collections 是另一个应该始终包含在 Java 应用程序中的库,它允许您使用 CollectionUtils.transform(args,new ConstantTransformer&lt;String, String&gt;("?")) 来实现这一点。然后将结果传递给我最初提到的连接。当然,这在 Java 中变得有点笨拙,更命令式的方法可能更合适。

    为了比较,整个事情都可以用 Groovy 和许多其他语言解决,比如args.collect{'?'}.join(',')。在 Java 中,使用我提到的实用程序,这更像是:

    StringUtils.join(
        CollectionUtils.transform(args, 
                                  new ConstantTransformer<String, String>("?")),
        ",");
    

    可读性差很多...

    【讨论】:

    • 感谢您介绍join。但看起来它不能应用于我的案例。我想要"?, ?, ?",而join 返回"foo,bar,data"
    【解决方案7】:

    我建议在这里使用StringBuilder 和经典的for 循环。

    String pattern = "";
    if (args.size() > 0) {
        StringBuilder sb = new StringBuilder("?");
        for(int i = 1; i < args.size(); i++) {
            sb.append(", ?");
        }
        pattern = sb.toString();
    }
    


    如果您不想使用 for 循环(正如您所说的不够简洁),请改用 while
    int count;
    String pattern = "";
    if ((count = args.size()) > 0) {
        StringBuilder sb = new StringBuilder("?");
        while (count-- > 1) {
            sb.append(", ?");
        }
        pattern = sb.toString();
    }
    

    另外,请参阅When to use StringBuilder?

    当您在循环中连接时 - 通常是编译器无法自行替换 StringBuilder。

    【讨论】:

    • 在这种情况下,有什么特别的理由更喜欢StringBuilder 而不是String
    • @Deqing 看看When to use StringBuilder 和这个answer。另外,更新了我的答案以使用 while 而不是您似乎不想要的 for
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多