Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最后一个元素的特殊大小写的最佳循环习惯用法_Java_Loops_While Loop_Idioms - Fatal编程技术网

Java 最后一个元素的特殊大小写的最佳循环习惯用法

Java 最后一个元素的特殊大小写的最佳循环习惯用法,java,loops,while-loop,idioms,Java,Loops,While Loop,Idioms,在执行简单的文本处理和打印语句时,我多次遇到这种情况,其中我在集合上循环,我想对最后一个元素进行特殊处理(例如,除最后一个之外,每个普通元素都用逗号分隔) 是否有一些最佳实践习惯用法或优雅的形式,不需要重复代码或在if、else循环中插入 例如,我有一个字符串列表,我想打印在逗号分隔的列表中。(do-while解决方案已经假设列表中有2个或更多元素,否则它将与更正确的带有条件的for循环一样糟糕) e、 g.列表=(“狗”、“猫”、“蝙蝠”) 我想打印“[狗,猫,蝙蝠]” 我提出了两种方法 带条

在执行简单的文本处理和打印语句时,我多次遇到这种情况,其中我在集合上循环,我想对最后一个元素进行特殊处理(例如,除最后一个之外,每个普通元素都用逗号分隔)

是否有一些最佳实践习惯用法或优雅的形式,不需要重复代码或在if、else循环中插入

例如,我有一个字符串列表,我想打印在逗号分隔的列表中。(do-while解决方案已经假设列表中有2个或更多元素,否则它将与更正确的带有条件的for循环一样糟糕)

e、 g.列表=(“狗”、“猫”、“蝙蝠”)

我想打印“[狗,猫,蝙蝠]”

我提出了两种方法

  • 带条件的For循环

    public static String forLoopConditional(String[] items) {
    
    String itemOutput = "[";
    
    for (int i = 0; i < items.length; i++) {
        // Check if we're not at the last element
        if (i < (items.length - 1)) {
            itemOutput += items[i] + ", ";
        } else {
            // last element
            itemOutput += items[i];
        }
    }
    itemOutput += "]";
    
    return itemOutput;
     }
    
  • 在Java AbstractCollection类中,它有以下实现(有点冗长,因为它包含所有边缘大小写错误检查,但还不错)

    公共字符串toString(){
    迭代器i=迭代器();
    如果(!i.hasNext())
    返回“[]”;
    StringBuilder sb=新的StringBuilder();
    某人附加(“[”);
    对于(;;){
    E=i.next();
    附加(e==这个?”(这个集合):e);
    如果(!i.hasNext())
    返回sb.append(']').toString();
    某人加上(“,”);
    }
    }
    

    或者说,这是相当可读的。当然,您可以将条件放在单独的
    if
    子句中。它的惯用之处(至少我认为是这样)在于它使用foreach循环,而不使用复杂的循环头


    此外,没有重复的逻辑(即,
    items
    中的项目只有一个地方实际附加到输出字符串中-在实际应用程序中,这可能是一个更复杂和冗长的格式化操作,因此我不想重复代码)。

    我喜欢为第一个项目使用标志

     ArrayList<String> list = new ArrayList()<String>{{
           add("dog");
           add("cat");
           add("bat");
        }};
        String output = "[";
        boolean first = true;
        for(String word: list){
          if(!first) output += ", ";
          output+= word;
          first = false;
        }
        output += "]";
    
    ArrayList list=new ArrayList(){{
    添加(“狗”);
    添加(“cat”);
    添加(“bat”);
    }};
    字符串输出=“[”;
    布尔值优先=真;
    for(字符串字:列表){
    如果(!first)输出+=“,”;
    输出+=字;
    第一个=假;
    }
    输出+=“]”;
    
    第三种选择如下

    StringBuilder output = new StringBuilder();
    for (int i = 0; i < items.length - 1; i++) {
        output.append(items[i]);
        output.append(",");
    }
    if (items.length > 0) output.append(items[items.length - 1]);
    
    FWIW,Apache Commons中的(第3232行之后)确实在循环中使用了if,不过:

    public static String join(Object[] array, char separator, int startIndex, int endIndex)     {
            if (array == null) {
                return null;
            }
            int bufSize = (endIndex - startIndex);
            if (bufSize <= 0) {
                return EMPTY;
            }
    
            bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().length()) + 1);
            StringBuilder buf = new StringBuilder(bufSize);
    
            for (int i = startIndex; i < endIndex; i++) {
                if (i > startIndex) {
                    buf.append(separator);
                }
                if (array[i] != null) {
                    buf.append(array[i]);
                }
            }
            return buf.toString();
        }
    
    公共静态字符串联接(对象[]数组、字符分隔符、int-startIndex、int-endIndex){
    if(数组==null){
    返回null;
    }
    int bufSize=(endIndex-startIndex);
    if(bufSize startIndex){
    追加(分隔符);
    }
    if(数组[i]!=null){
    追加(数组[i]);
    }
    }
    返回buf.toString();
    }
    
    如果像那样动态构建字符串,则不应使用+=运算符。
    StringBuilder
    类对于重复的动态字符串连接工作得更好

    public String commaSeparate(String[] items, String delim){
        StringBuilder bob = new StringBuilder();
        for(int i=0;i<items.length;i++){
            bob.append(items[i]);
            if(i+1<items.length){
               bob.append(delim);
            }
        }
        return bob.toString();
    }
    

    我通常编写一个for循环,如下所示:

    public static String forLoopConditional(String[] items) {
        StringBuilder builder = new StringBuilder();         
    
        builder.append("[");                                 
    
        for (int i = 0; i < items.length - 1; i++) {         
            builder.append(items[i] + ", ");                 
        }                                                    
    
        if (items.length > 0) {                              
            builder.append(items[items.length - 1]);         
        }                                                    
    
        builder.append("]");                                 
    
        return builder.toString();                           
    }       
    
    static String commaSeparated(String[] items) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (String item: items) {
            sb.append(sep);
            sb.append(item);
            sep = ",";
        }
        return sb.toString();
    }
    
    公共静态字符串forLoopConditional(字符串[]项){
    StringBuilder=新的StringBuilder();
    生成器。追加(“[”);
    对于(inti=0;i0){
    builder.append(items[items.length-1]);
    }                                                    
    生成器。追加(“]”);
    返回builder.toString();
    }       
    
    我认为更容易将第一个元素视为特例,因为更容易知道迭代是否是第一个而不是最后一个。不需要任何复杂或昂贵的逻辑就可以知道某件事情是否是第一次做的

    public static String prettyPrint(String[] items) {
        String itemOutput = "[";
        boolean first = true;
    
        for (int i = 0; i < items.length; i++) {
            if (!first) {
                itemOutput += ", ";
            }
    
            itemOutput += items[i];
            first = false;
        }
    
        itemOutput += "]";
        return itemOutput;
    }
    
    公共静态字符串预打印(字符串[]项){
    字符串itemOutput=“[”;
    布尔值优先=真;
    对于(int i=0;i
    在本例中,您实际上是在使用一些分隔符字符串连接字符串列表。你可以自己写一些东西来做这个。然后你会得到如下结果:

    String[] items = { "dog", "cat", "bat" };
    String result = "[" + joinListOfStrings(items, ", ") + "]"
    

    公共静态字符串JoinListOfstring(字符串[]项,字符串sep){
    字符串缓冲结果;
    
    对于(int i=0;i,因为您的案例只是处理文本,所以在循环中不需要条件。C示例:

    char* items[] = {"dog", "cat", "bat"};
    char* output[STRING_LENGTH] = {0};
    char* pStr = &output[1];
    int   i;
    
    output[0] = '[';
    for (i=0; i < (sizeof(items) / sizeof(char*)); ++i) {
        sprintf(pStr,"%s,",items[i]);
        pStr = &output[0] + strlen(output);
    }
    output[strlen(output)-1] = ']';
    
    char*items[]={“狗”、“猫”、“蝙蝠”};
    char*输出[STRING_LENGTH]={0};
    char*pStr=&输出[1];
    int i;
    输出[0]='[';
    对于(i=0;i<(sizeof(items)/sizeof(char*);+i){
    sprintf(pStr,“%s”,项目[i]);
    pStr=&output[0]+strlen(输出);
    }
    输出[strlen(输出)-1]=']';
    

    与其添加条件以避免生成尾随逗号,不如继续生成它(以保持循环简单且无条件),并在末尾简单地覆盖它。很多时候,我发现生成特殊情况更为清晰,就像任何其他循环迭代一样,然后在结尾手动替换它(尽管“替换它”代码不止几行,这种方法实际上会变得更难阅读。)

    我通常的做法是测试索引变量是否为零,例如:

    var result = "[ ";
    for (var i = 0; i < list.length; ++i) {
        if (i != 0) result += ", ";
        result += list[i];
    }
    result += " ]";
    
    var result=“[”;
    对于(变量i=0;i

    但是,当然,只有当我们讨论没有数组的语言时,才会这样做。join(“,”)方法;-

    我通常这样写:

    public static String forLoopConditional(String[] items) {
        StringBuilder builder = new StringBuilder();         
    
        builder.append("[");                                 
    
        for (int i = 0; i < items.length - 1; i++) {         
            builder.append(items[i] + ", ");                 
        }                                                    
    
        if (items.length > 0) {                              
            builder.append(items[items.length - 1]);         
        }                                                    
    
        builder.append("]");                                 
    
        return builder.toString();                           
    }       
    
    static String commaSeparated(String[] items) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (String item: items) {
            sb.append(sep);
            sb.append(item);
            sep = ",";
        }
        return sb.toString();
    }
    

    我将使用您的第二个示例,即在循环之外处理特殊情况,只需将其写得更简单一些:

    String itemOutput = "[";
    
    if (items.length > 0) {
        itemOutput += items[0];
    
        for (int i = 1; i < items.length; i++) {
            itemOutput += ", " + items[i];
        }
    }
    
    itemOutput += "]";
    
    字符串项输出=
    
    public static String joinListOfStrings(String[] items, String sep) {
        StringBuffer result;
        for (int i=0; i<items.length; i++) {
            result.append(items[i]);
            if (i < items.length-1) buffer.append(sep);
        }
        return result.toString();
    }
    
    char* items[] = {"dog", "cat", "bat"};
    char* output[STRING_LENGTH] = {0};
    char* pStr = &output[1];
    int   i;
    
    output[0] = '[';
    for (i=0; i < (sizeof(items) / sizeof(char*)); ++i) {
        sprintf(pStr,"%s,",items[i]);
        pStr = &output[0] + strlen(output);
    }
    output[strlen(output)-1] = ']';
    
    string value = "[" + StringUtils.join( items, ',' ) + "]";
    
    var result = "[ ";
    for (var i = 0; i < list.length; ++i) {
        if (i != 0) result += ", ";
        result += list[i];
    }
    result += " ]";
    
    static String commaSeparated(String[] items) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (String item: items) {
            sb.append(sep);
            sb.append(item);
            sep = ",";
        }
        return sb.toString();
    }
    
    String itemOutput = "[";
    
    if (items.length > 0) {
        itemOutput += items[0];
    
        for (int i = 1; i < items.length; i++) {
            itemOutput += ", " + items[i];
        }
    }
    
    itemOutput += "]";
    
    List<String> strings = Arrays.asList("The", "Cat", "in", "the", "Hat);
    
    System.out.println(strings.toString());
    
    public class Dog {
        private String name;
    
        public Dog(String name){
             this.name = name;
        }
    
        public String toString(){
            return name;
        }
    }
    
    List<Dog> dogs = Arrays.asList(new Dog("Frank"), new Dog("Hal"));
    System.out.println(dogs);
    
    for ( s1; exit-condition; s2 ) {
        doForAll();
        if ( !modified-exit-condition ) 
            doForAllButLast();
    }
    
    for ( s1;; s2 ) {
        doForAll();
    if ( modified-exit-condition ) break;
        doForAllButLast();
    }
    
    for (int i = 0;; i++) {
        itemOutput.append(items[i]);
    if ( i == items.length - 1) break;
        itemOutput.append(", ");
    }
    
    Iterator<String> itemIterator = Arrays.asList(items).iterator();
    if (itemIterator.hasNext()) {
      // special-case first item.  in this case, no comma
      while (itemIterator.hasNext()) {
        // process the rest
      }
    }
    
    join [] = ""
    join [x] = x
    join (x:xs) = concat [x, ",", join xs]
    
    surround before after str = concat [before, str, after]
    
    yourFunc = surround "[" "]" . join
    
    -- example usage: yourFunc ["dog", "cat"] will output "[dog,cat]"
    
    join [] = ""
    join strings = foldr1 (\a b -> concat [a, ",", b]) strings 
    
    public static string Join(List<string> strings)
    {
        if (!strings.Any()) return string.Empty;
        return strings.Aggregate((acc, val) => acc + "," + val);
    }
    
    public static String join(String[] items) {
        if (items.length == 0) return "";
        if (items.length == 1) return items[0];
    
        StringBuilder result = new StringBuilder();
        for(int i = 0; i < items.length - 1; i++) {
            result.append(items[i]);
            result.append(",");
        }
        result.append(items[items.length - 1]);
        return result.toString();
    }
    
    String res = Arrays.stream(items).reduce((t, u) -> t + "," + u).get();
    
    List<String> items = Arrays.asList("dog", "cat", "bat");
    String result = items.stream().collect(Collectors.joining(", ", "[", "]"));
    System.out.println(result);