raullalves
raullalves

Reputation: 856

How to combine two lists without using foreach?

Originally, I have this code:

String[] A;
String[] B;
//...
List<String> myList= new ArrayList<>(A.length + B.length);
for (int i= 0; i< B.length; i++){
   myList.add(A[i]);
   myList.add("*".equals(B[i]) ? B[i] : doSomethingWith(B[i]));
}

How to refactor if using, preferably, Java 8?

If for instance I have these arrays

A = {"one", "two", "three", "four"}

B = {"five", "six", "seven", "eight"}

At the end of the code, myList will be:

myList = {"one", "five", "two", "six", "three", "seven", "four", "eight"}

Upvotes: 4

Views: 1083

Answers (2)

hnefatl
hnefatl

Reputation: 6037

I personally don't think this needs refactoring as any "streamed" code will be less readable and less intuitive than your existing code, but as a pure proof-of-concept:

String[] A;
String[] B;
List<String> myList;

myList = IntStream.range(0, B.length)
                  .mapToObj(i -> new String[]
                      {
                          A[i],
                          "*".equals(B[i]) ? B[i] : doSomethingWith(B[i])
                      })
                  .flatMap(Arrays::stream)
                  .collect(Collectors.toList());

Working demo.


  • We use IntStream.range to provide the indices into our arrays.

  • mapToObj maps each index to an array containing the elements we want (this stage is also needed as IntStream::flatMap can only convert to another IntStream, we want to convert it to a Stream of Strings).

  • flatMap maps each array to a stream, then "flattens" the resulting stream of streams.

  • Finally, we just collect the results.

Upvotes: 5

Patr&#237;cia Espada
Patr&#237;cia Espada

Reputation: 248

Try something like this:

 String[] A;
 String[] B;
 //...
 List<String> myList= Arrays.asList (A);
 List<String> myList2 = Arrays.stream(B).map(
    (x)->"*".equals(x) ? x : doSomethingWith(x))
    .collect(Collectors.toList());
 myList.addAll(myList2);

Upvotes: -2

Related Questions