Best Loop Idiom for special casing the last element

后端 未结 18 966
梦毁少年i
梦毁少年i 2020-12-23 09:25

I run into this case a lot of times when doing simple text processing and print statements where I am looping over a collection and I want to special case the last element (

相关标签:
18条回答
  • string value = "[" + StringUtils.join( items, ',' ) + "]";
    
    0 讨论(0)
  • 2020-12-23 09:54

    In this case, you are essentially concatenating a list of strings using some separator string. You can maybe write something yourself which does this. Then you will get something like:

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

    with

    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();
    }
    

    If you have a Collection instead of a String[] you can also use iterators and the hasNext() method to check if this is the last or not.

    0 讨论(0)
  • 2020-12-23 09:56

    I usually write it like this:

    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();
    }
    
    0 讨论(0)
  • 2020-12-23 09:56

    Java 8 solution, in case someone is looking for it:

    String res = Arrays.stream(items).reduce((t, u) -> t + "," + u).get();
    
    0 讨论(0)
  • 2020-12-23 09:56

    A third alternative is the following

    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]);
    

    But the best is to use a join()-like method. For Java there's a String.join in third party libraries, that way your code becomes:

    StringUtils.join(items,',');
    

    FWIW, the join() method (line 3232 onwards) in Apache Commons does use an if within a loop though:

    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();
        }
    
    0 讨论(0)
  • 2020-12-23 09:58

    I think it is easier to think of the first element as the special case because it is much easier to know if an iteration is the first rather than the last. It does not take any complex or expensive logic to know if something is being done for the first time.

    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;
    }
    
    0 讨论(0)
提交回复
热议问题