Scala query expressions can be used for queries similar to some C# LINQ expressions

While Java does not have any powerful query language similar to LINQ, Scala does indeed have some possibilities to write at least some of the queries that are possible with LINQ. Below are some examples comparing LINQ query syntax with similar Scala queries:


C# LINQ code: int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNums = from n in numbers where n < 5 select n; Similar Scala code: val numbers = List(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) // alternatively val numbers = Array(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) val lowNums = for { number <- numbers if (number < 5) } yield number
C# LINQ code: int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var numsPlusOne = from n in numbers select n + 1; Similar Scala code: val numbers = List(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) val numsPlusOne = for { n <- numbers } yield n + 1
C# LINQ code: int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var textNums = from n in numbers select strings[n]; Similar Scala code: val numbers = List(5, 4, 1, 3, 9, 8, 6, 7, 2, 0) val strings = List("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") val textNums = for { n <- numbers } yield strings(n)
C# LINQ code: var productNames = from p in products select p.ProductName; Similar Scala code, returning a List of Strings: val productNames = for { p <- products } yield p.ProductName ( where the Scala Product class might be defined something as below, with at least the String field returned class Product(val ProductName String) { override def toString = " [[ProductName " + ProductName + "]] " } val products = List(new Product("some product name"), [...] )) )
C# LINQ code: var expensiveInStockProducts = from p in products where p.UnitsInStock > 0 && p.UnitPrice > 3.00 select p; Similar Scala code: val expensiveInStockProducts = for { p <- products if (p.UnitsInStock > 0 && p.UnitPrice > 3.00) } yield p ( where the Scala Product class might be defined something as below, with at least the two fields used in the above query: class Product(val UnitsInStock: Int, val UnitPrice: Double) { override def toString = " [[UnitsInStock: " + UnitsInStock + " ; UnitPrice:" + UnitPrice + "]] " } val products = List(new Product(3, 5.2), [...] )) )

Now a reasonable question would of course be how to implement these kind of queries in Java. Well, while there seems to be no useful interfaces and methods in the Java core library, you might use the specification pattern to be able to implement at least some kind of queries. For example, a simplified version of it (i.e. without the AND/OR/NOT impementations, as in the wikipedia page linked above) might be implemented like this:

public interface Specification<T> {
    boolean isSatisfiedBy(T t);
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionUtility {
    public static <T> List<T> findAllItemsMatchingSpecification(
        final Iterable<T> iterableElements,
        final Specification<T> specification
    ) {
        final List<T> listOfElementsmatchingSpecification = new ArrayList<T>();
        for (T element : iterableElements) {
            if(specification.isSatisfiedBy(element)) {
                listOfElementsmatchingSpecification.add(element);        
            }
        }
        return Collections.unmodifiableList(listOfElementsmatchingSpecification);
    }
}

Then the last of the C# and Scala queries above (which queried Products by looking at the values of UnitsInStock and UnitPrice) might be implemented like below, using the above Specification interface and utility method:

final List<Product> products = Arrays.asList(new Product( [...] ), [ ... ]);

final List<Product> productsMatchingSpecification = CollectionUtility.findAllItemsMatchingSpecification(
    products,
    new Specification<Product>() {
	public boolean isSatisfiedBy(Product product) {
	    return (product.getUnitsInStock() > 0 && product.getUnitPrice() > 3.00);
	}
    }
);

While the specification pattern indeed is nice to use in a language such as Java, for being able to define flexible filtering through an interface and reusable methods, it is even nicer with the kind of queries that you can write with Scala (and C#) and its core library.

/ Tomas Johansson, Stockholm, Sweden, 2010-01-24