Overview
Java Streams and C# LINQ both offer a declarative way to process collections. While they share many similarities, there are differences in syntax and functionality. Below, we transfer our knowledge of Java Streams into C# LINQ.
Basic Setup
In Java, you typically import the necessary classes from the java.util.stream
package. In C#, LINQ is available through the System.Linq
namespace.
Four main concepts: Filtering, mapping, sorting and reducing
Concept #1: Filtering
Filtering allows you to select elements from a collection based on a condition. In both Java Streams and C# LINQ, this is done using the filter
and Where
methods respectively.
Pretty similar so far, huh?
Concept #2: Mapping
Mapping transforms each element in a collection into another form. Java Streams use the map
method, while C# LINQ uses the Select
method.
Concept #3: Sorting
Sorting arranges the elements in a collection in a particular order. Java Streams use the sorted
method, while C# LINQ uses the OrderBy
method.
Concept #4: Reducing
Reducing combines all elements in a collection into a single result using an accumulator function. Java Streams use the reduce
method, while C# LINQ uses the Aggregate
method.
Let's talk about types..
In Java, Streams work primarily with objects, and primitive types are handled using specialized streams like IntStream
, LongStream
, and DoubleStream
. In C#, LINQ works with any IEnumerable<T>
and provides similar functionality for primitive types using the same interface:
IEnumerable<T> and IOrderedEnumerable<T>
In C#, IEnumerable<T>
is a generic interface that represents a sequence of elements. It is the base interface for all collections that can be enumerated. It is similar to the Stream<T>
in Java, which also represents a sequence of elements and supports aggregate operations. Both are used to process collections in a declarative manner, though Stream<T>
is more specifically tied to Java's Stream API for functional-style operations on sequences.
IOrderedEnumerable<T>
is an interface that represents a sorted sequence of elements. It extends IEnumerable<T>
and is typically returned by sorting methods such as OrderBy
and ThenBy
. In Java, the equivalent would be a Stream<T>
that has been sorted using the sorted
method. Both interfaces represent sorted sequences and are used to maintain the order of elements as defined by the sorting criteria.
Complex Queries
Now let's look at a few complex examples that combine filtering, mapping, and reducing:
In this example, we filter the list to include only items that contain the letter "a", sort them alphabetically, map them to their lengths, and then sum these lengths.
This example filters for even numbers, sorts them in descending order, doubles each number, and then sums the results.
In this more complex example, we filter people older than 20, sort them by name, map them to their ages, and sum the ages.
Conclusion
Java Streams | C# LINQ |
---|---|
filter | Where |
map | Select |
sorted() | OrderBy(item => item) |
collect(Collectors.toList()) | ToList() |
reduce | Aggregate |
Both Java Streams and C# LINQ provide powerful capabilities for processing collections. While the syntax and some features differ, the core concepts are very similar. If you are interested in leveraging your existing Java knowledge to learn C# efficiently and in-depth, check out our Java to C# Transfer Course.
Happy coding!
Related glossary entry: Functional-style data processing