Java equivalent of PHP's implode(',' , array_filter( array () ))

前端 未结 9 1126
自闭症患者
自闭症患者 2020-12-29 19:32

I often use this piece of code in PHP

$ordine[\'address\'] = implode(\', \', array_filter(array($cliente[\'cap\'], $cliente[\'citta\'], $cliente[\'provincia\'         


        
相关标签:
9条回答
  • 2020-12-29 19:59

    A simple Implode

    public static String implode(String glue, String[] strArray)
    {
        String ret = "";
        for(int i=0;i<strArray.length;i++)
        {
            ret += (i == strArray.length - 1) ? strArray[i] : strArray[i] + glue;
        }
        return ret;
    }
    

    You can create overloads for it..

    The above it equivalent of php implode.
    Here is what you want:

    import java.lang.*
    public static String customImplode(String glue, String[] strArray)
    {
        String ret = "";
        for(int i=0;i<strArray.length;i++)
        {
            if (strArray[i].trim() != "")
                ret += (i == strArray.length - 1) ? strArray[i] : strArray[i] + glue;
        }
        return ret;
    }
    
    0 讨论(0)
  • 2020-12-29 20:03

    Updated version using Java 8 (original at the end of post)

    If you don't need to filter any elements you can use

    • String.join(CharSequence delimiter, CharSequence... elements)

      • String.join(" > ", new String[]{"foo", "bar"});
      • String.join(" > ", "foo", "bar");

    • or String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

      • String.join(" > ", Arrays.asList("foo", "bar"));

    Since Java 8 we can use StringJoiner (instead of originally used StringBulder) and simplify our code.
    Also to avoid recompiling " *" regex in each call of matches(" *") we can create separate Pattern which will hold its compiled version in some field and use it when needed.

    private static final Pattern SPACES_OR_EMPTY = Pattern.compile(" *");
    public static String implode(String separator, String... data) {
        StringJoiner sb = new StringJoiner(separator);
        for (String token : data) {
            if (!SPACES_OR_EMPTY.matcher(token).matches()) {
                sb.add(token);
            }
        }
        return sb.toString();
    }   
    

    With streams our code can look like.

    private static final Predicate<String> IS_NOT_SPACES_ONLY = 
            Pattern.compile("^\\s*$").asPredicate().negate();
    
    public static String implode(String delimiter, String... data) {
        return Arrays.stream(data)
                .filter(IS_NOT_SPACES_ONLY)
                .collect(Collectors.joining(delimiter));
    }
    

    If we use streams we can filter elements which Predicate. In this case we want predicate to accept strings which are not only spaces - in other words string must contain non-whitespace character.

    We can create such Predicate from Pattern. Predicate created this way will accept any strings which will contain substring which could be matched by regex (so if regex will look for "\\S" predicate will accept strings like "foo ", " foo bar ", "whatever", but will not accept " " nor " ").

    So we can use

    Pattern.compile("\\S").asPredicate();
    

    or possibly little more descriptive, negation of strings which are only spaces, or empty

    Pattern.compile("^\\s*$").asPredicate().negate();
    

    Next when filter will remove all empty, or containing only spaces Strings we can collect rest of elements. Thanks to Collectors.joining we can decide which delimiter to use.


    Original answer (before Java 8)

    public static String implode(String separator, String... data) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length - 1; i++) {
        //data.length - 1 => to not add separator at the end
            if (!data[i].matches(" *")) {//empty string are ""; " "; "  "; and so on
                sb.append(data[i]);
                sb.append(separator);
            }
        }
        sb.append(data[data.length - 1].trim());
        return sb.toString();
    }
    

    You can use it like

    System.out.println(implode(", ", "ab", " ", "abs"));
    

    or

    System.out.println(implode(", ", new String[] { "ab", " ", "abs" }));
    

    Output ab, abs

    0 讨论(0)
  • 2020-12-29 20:03

    Using Streams (for Java 8 and later) would be an alternate possible solution for this.

    You are required to import

    java.util.stream.Collectors;
    

    to use the join process

    You may use:

    Arrays.asList("foo","bar").stream().collect(Collectors.joining(","));
    

    to achieve the desired result.

    0 讨论(0)
提交回复
热议问题