Example Code: Using Java Streams in BoxLang

Here’s a couple quick code samples of how awesome Java Streams are to use now in BoxLang. In the past, CF lacked the proper Java interop to directly use streams, which is why we created CF libraries like cbstreams. Java Streams ARE crazy super powerful and you should probably check them out. They make CF’s simple data structures and limited functional abilities look pretty lame to be honest. Streams have been around since Java 8, and it’s sad to see how CF has fallen behind in comparison.

You can do a million things with streams, including super easy parallel operations, but this isn’t a primer on everything streams do. Two of the features streams provide (partitioning and grouping) came up in another thread so I cooked up a couple examples to show how easy BoxLang has made it to dip down into java, even being able to provide first-class BL functions as Java functional interfaces.

Both of these examples can be pasted right into https://try.boxlang.io :slight_smile:

This example takes an array of numbers and separates the odds from the evens. A true/false predicate is used to examine each value, and the result is two arrays of separated values:

import java.util.stream.Collectors;

result = [1, 2, 4, 6, 7, 9, 10, 11]
  .stream()
  .collect( 
    Collectors.partitioningBy( n -> n % 2 == 0 ) // Is even?
  );

println( result ) // {false=[1, 7, 9, 11], true=[2, 4, 6, 10]}

This next example is a bit meatier, but still quite simple. It takes a query object (which is represented as a stream of structs for each row) and performs the following processing on it.

  • Group the rows by country
  • Map the results to just the name
  • Collect the results into a Java List, which you can use just like a native BoxLang Array.

And what’s cool is it performs all of that in parallel threads using the JVM’s default fork-join pool!

import java.util.stream.Collectors;

result = myQry = queryNew( 
  "name,country",
  "varchar,varchar",
  [ 
    ["Luis","El Salvador"], 
    ["Jon","US"], 
    ["Brad","US"],
    ["Eric","US"],
    ["Jorge","Switzerland"], 
    ["Majo","El Salvador"], 
    ["Jaime","El Salvador"], 
    ["Esme","Mexico"]
  ])
  .stream()
  .parallel()
  .collect( 
    Collectors.groupingBy(  row -> row.country,
      Collectors.mapping( row -> row.name,
        Collectors.toList()  )
    ) );

// {El Salvador=[Luis, Majo, Jaime], Mexico=[Esme], Switzerland=[Jorge], US=[Jon, Brad, Eric]}
println( result )

These two examples are just the tip of the iceberg, and you CANNOT do this in CF because of it’s lack of proper Java interop. This is the sort of sweet Java abilities we’re aiming to expose in BoxLang.

6 Likes

That’s https://try.boxlang.io/ for those trying the link. It’s missing the “L”.

Oops, thanks. Fixed!