Java 8 threads: conditional collector

I want to use Java 8 threads to convert String values ​​to a single string. A list of values, such as "A", "B", should return a String as "Values:" A "," B "added." This works fine, however I want to change Pre- and Postfix depending on the number of values. For example, if I have a list with only "A", I want the resulting row to be "Value" A added. "

import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;

public class HelloWorld
{
  public static void main(String[] args)
  {
    List<String> values = new ArrayList<>();
    values.add("A");
    values.add("B");
    values.add("C");
    List<String> value = new ArrayList<>();
    value.add("A");
    System.out.println(log(values));
    System.out.println(log(value));
  }
  public static String log(List<String> values){
    return values.stream()
                 //.filter(...)
                 .map(x -> "'" + x + "'")
                 .collect(Collectors.joining(",","values:"," added"));

  }
}

Is there a way to change the Collctor, depending on the size of the resulting list? Then I could do something like

.collect(Collectors.joining(",", size = 1 ? "Value " : "Values: "," added"));

I would prefer a single-thread operation without an intermediate result. I also do not know the result in advance, because I am filtering the stream.

: , . . !

import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;


public class HelloWorld
{

  public static void main(String[] args)
  {
    List<String> oldValues = new ArrayList<>();
    oldValues.add("A");
    oldValues.add("B");
    oldValues.add("C");
    List<String> newValues = new ArrayList<>();
    newValues.add("A");
    newValues.add("C");
    newValues.add("D");
    newValues.add("E");
    System.out.println(HelloWorld.<String>log(oldValues, newValues, " deleted"));
    System.out.println(HelloWorld.<String>log(newValues, oldValues, " added"));
  }

    public static <T> String log(List<T> first, List<T> second, String postfix) {
        return  (String) first
                .stream()
                .filter(x -> !second.contains(x))
                .map(x -> "'" + x.toString() + "'").
                collect(Collectors.collectingAndThen(Collectors.toList(),
                    list -> {
                        if (list.size() == 1) {
                            return "Value " + list.get(0) + postfix;
                        }
                        if (list.size() > 1) {
                            List<String> strings = new ArrayList<>(list.size());
                            for (Object object : list) {
                                strings.add(object.toString());
                            }
                            return "Values: " + String.join(",", strings) +  postfix;
                        }
                        return "";
                    }));
    }
}

:

Value 'B' deleted
Values: 'D','E' added
+4
5

:

 return values.stream()
            .map(x -> "'" + x + "'")
            .collect(Collectors.collectingAndThen(Collectors.toList(),
                    list -> {
                        if (list.size() == 1) {
                            return "value" + list.get(0);
                        }
                        if (list.size() > 1) {
                            return String.join(",", list);
                        }
                        return "Nothing found";
                    }));
+2

, StringJoiner, joining(), " ", . , , .

public static String log(List<String> values) {
    return values.stream()
                 //.filter(...)
                 .collect(
                         () -> new Object() {
                             StringJoiner sj = new StringJoiner("', '", "'", "' added");
                             int num;
                             String result() {
                                 return num==0? "No values added":
                                                (num==1? "Value ": "Values ")+sj;
                             }
                         },
                         (o,s) -> { o.sj.add(s); o.num++; },
                         (o,p) -> { o.sj.merge(p.sj); o.num+=p.num; }
                 ).result();
}

, "" ; , - .

System.out.println(log(Arrays.asList("A", "B", "C")));
System.out.println(log(Arrays.asList("A")));
System.out.println(log(Collections.emptyList()));
Values 'A', 'B', 'C' added
Value 'A' added
No values added
+4

, , . (, count), () . collect , . , , .

( , ), "Value" "Values".

+2

, , ( , ):

public static String log(List<String> values) {
    List<String>
        elements = values.stream()
                       //.filter(...)
                         .map(x -> "'" + x + "'")
                         .collect(Collectors.toList());
    String joined = String.join (",", elements);
    return (elements.size () == 1 ? "value " : "values:") + joined + " added";
}

It does not seem like a good idea to count elements through some side effect of one of the intermediate methods Stream.

+2
source

And another interesting option is likely to be as follows:

public static String log(List<String> values) {
    Spliterator<String> sp = values.stream()
            .map(x -> "'" + x + "'")
            .spliterator();

    StringBuilder sb = new StringBuilder("Value = ");

    sp.tryAdvance(x -> sb.append(x));
    if (sp.tryAdvance(x -> {
        sb.replace(5, 6, "s ");
        sb.append(",").append(x);
    })) {
        sp.forEachRemaining(x -> {
            sb.append(",").append(x);
        });
    }

    return sb.toString();

}

The advantage is that you do not need to collect in Listto additionally add each of them separately.

+2
source

Source: https://habr.com/ru/post/1692255/


All Articles