Joining Java Streams

Java 8 introduced some impressive new features. Lambdas in conjunction with Streams finally support a functional style of programming.

But, unlike LINQ of the .NET world, there is no operator to join streams. Thus, I tried to join streams manually. My approach is to use second a stream in a lambda expression within a map operation. Other options are thinkable.Here a very simple example, without further explanation:

package com.mycompany.testlambda;

import java.util.ArrayList;
import java.util.List;

public class Starter {

       public static void main(String[] args) {
               List<Color> colors = initColors();
               // just print the color names
               colors.stream().forEach(color -> System.out.println(color.getName()));
               List<Car> cars = new ArrayList<>();
               initCars(cars);
               // just print the car names
               cars.stream().map(car -> car.getName()).forEach(System.out::println);
               // next, join color name to car and print carName: colorName
               // sample 1: access to collection
               cars.stream()
                               .map(car -> car.getName() + ": " + colors
                                               .get(car.getColorId())
                                               .getName())
                               .forEach(System.out::println);
               // sample 2: "joining" streams
               cars.stream()
                               .map(car -> car.getName() + ": " + colors
                                               .stream()
                                               .filter(color -> color.getId() == car.getColorId())
                                               .findAny().get().getName())
                               .forEach(System.out::println);

       }

       private static void initCars(List<Car> cars) {
               cars.add(new Car("VW", 1));
               cars.add(new Car("Ford", 2));
               cars.add(new Car("Chevrolet", 1));
               cars.add(new Car("BMW", 3));
               cars.add(new Car("Ferrari", 1));
               cars.add(new Car("Mercedes", 2));
               cars.add(new Car("Mercedes", 3));
       }

       private static List<Color> initColors() {
               List<Color> colors = new ArrayList<>();
               colors.add(new Color(0, "unknown"));
               colors.add(new Color(1, "red"));
               colors.add(new Color(2, "green"));
               colors.add(new Color(3, "blue"));
               return colors;
       }
}

2 thoughts on “Joining Java Streams”

  1. When nesting streams, as in “Sample 2”, the call to the outer reference car.getColorId() is inefficient, because the result will be the same for each element of the inner stream. The inner lambda closes over the current “car” element of the outer lambda. Instead, I suggest caching the result of car.getColorId() in a local variable of the outer lambda and comparing color.getColorId() to that variable. In this simple example. the inefficiency is negligible. In real world applications, the redundancy cost could be very expensive.

    1. Jeffrey,

      With respect to performance, you’re absolutely right. My example isn’t optimized for anything. I just wanted to create a simple “join” of streams without considering any other aspect.

      Michael

Leave a Reply to Jeffrey Smith Cancel reply

Your email address will not be published. Required fields are marked *