SlideShare a Scribd company logo
1 of 23
Collections – Part VI 
Nico Ludwig (@ersatzteilchen)
2 
● Collections – Part VI 
TOC 
– Producing Collection Objects 
– Immutable Collections and defense Copies 
– Empty Collections 
– Tuples as pseudo Collections 
– Filling Collections with structured Data 
– Collections abstracting Data Processing: Stack and Queue 
– Kung Fu beyond Collections: .Net's LINQ and Java's Streams
Producing Collection Objects 
● Java: We already discussed Collections' simple factories producing collections in Java, but there exist more of these: 
3 
– The class Arrays provides similar simple factories: the method asList() produces an unmodifiable List from the passed array: 
public static void main(String[] args) throws Exception { 
List<String> arguments = Arrays.asList(args); // Creates an unmodifiable List from an array. 
} 
– Because asList() accepts a variable count of arguments, we can directly pass some values, instead of a first class array: 
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); // Creates a List from a couple of arguments. 
● .Net: There exist many means to produce collections through extension methods from the System.Linq namespace. 
– E.g. producing a List from an array with the extension method ToList(): 
public static void Main(string[] args) { 
IList<string> arguments = args.ToList(); // Creates a List from an array. 
} 
– .Net's class Enumerable provides the methods Range() and Repeat() (i.e. simple factories) to produce respective sequences. 
● The method-call chain with ToList() produces/materializes the lists from the sequences. - The resulting list is modifiable. 
IList<int> numbers = Enumerable.Range(1, 6).ToList(); // Creates a List of integers from 1 to 6 inclusively. 
IList<int> sixCopiesOf42 = Enumerable.Repeat(42, 6).ToList(); // Creates a List containing six copies of the integer 42.
4 
Immutable Collections – Part I 
● Immutability of objects is a relevant topic meanwhile to write robust applications. How is it supported for collections? 
● In C++, container objects can be idiomatically be set as const, then non-const member functions are no longer callable: 
// Defines a const vector containing some ints: 
const std::vector<int> numbers{1, 2, 3, 4, 5, 6}; 
// After the const vector was created it cannot be modified: 
numbers.push_back(7); // Results in a compile time error! 
// But reading is no problem: 
int value = numbers[0]; 
– The objects managed by a const std::vector cannot be modified as well! This is called const-correctness in C++. 
– (This idiomatic usage of const objects in C++ requires no further explanation.) 
● In the COCOA framework there exist mutable and immutable collections separately: 
// Defines an immutable NSArray containing some ints: 
NSArray* numbers = @[@1, @2, @3, @4, @5, @6]; 
// NSArray does not expose any methods that could modify numbers, therefor we 
// have to create an NSMutableArray from numbers: 
NSMutableArray* mutableNumbers = [NSMutableArray arrayWithArray:numbers]; 
// NSMutableArray provides methods to modify the collection: 
[mutableNumbers addObject:@7]; 
– NSMutableArray inherits from NSArray, this idea is used for other COCOA collections as well.
Immutable Collections – Part II 
// Defines a list containing some ints: 
IList<int> numbers = new List<int>{1, 2, 3, 4, 5, 6 }; 
// The mutable IList<int> will be wrapped by an immutable ReadOnlyCollection<int> (from the namespace System.Collections.ObjectModel): 
ReadOnlyCollection<int> readOnlyNumbers = new ReadOnlyCollection<int>(numbers); 
// ReadOnlyCollection<T> implements IList<T> so that it can partake in APIs requiring objects exposing that interface. 
// But IList<T> is implemented explicitly, so potentially mutable methods can not be directly called: 
readOnlyNumbers.Add(7); // Results in a compile time error. 
// If ReadOnlyCollection<T> is accessed via the IList<T> interface, calling potentially mutable methods will throw a NotSupportedException. 
IList<int> readOnlyNumbersAsList = readOnlyNumbers; 
readOnlyNumbersAsList.Add(7); // Results in a run time error: NotSupportedException will be thrown. 
5 
● The .Net framework follows another principle to provide immutability: wrapping. 
– Wrapping means, that a present instance is wrapped into another object in order to adopt another interface or to get another behavior. 
– Alternatively List<T>'s method AsReadOnly() can be used, which directly returns readonly wrappers. 
– The idea of wrapping is used for ReadOnlyDictionary as well. 
– Objects implementing ICollection<T> can be checked if these are readonly with the 
property ICollection<T>.IsReadOnly. 
● The design pattern we've encountered here is called wrapper or adapter. 
<<interface>> 
IList 
ReadOnlyCollection 
wraps 
implements 
T 
T 
// Directly create a ReadOnlyCollection<int> from a List<int> 
ReadOnlyCollection<int> readOnlyNumbers2 = new List<int>{1, 2, 3, 4, 5, 6 }.AsReadOnly();
6 
Immutable Collections – Part III 
● Java does also apply the wrapper principle to provide immutability. 
– Java hides the wrapper type completely from the caller, but exposes an unmodifiable object implementing a collection interface. 
– The unmodifiable implementation is somehow internally instantiated by the simple factory Collections.unmodifiable...(). 
// Defines a list containing some ints: 
List<Integer> numbers = new ArrayList<>(Arrays.<Integer>asList(1, 2, 3, 4, 5, 6)); 
// The mutable List<int> will be wrapped by an unmodifiable List<int>: 
List<Integer> readOnlyNumbers = Collections.unmodifiableList(numbers); // Calling the simple factory. 
// readOnlyNumbers' potentially mutable methods can be called, but these calls will throw UnsupportedOperationExceptions. 
readOnlyNumbers.add(7); // Results in a run time error: UnsupportedOperationException will be thrown. 
● Java: More simple factories can be found in the class Collections as static methods (unmodifiableSet(), unmodifiableMap()). 
– The return type of all of these simple factories are just interface types, the unmodifiable implementations are always hidden. 
– So the UML diagram of the relations between the contributing types looks like so: 
<<interface>> 
List 
exposes implements 
HiddenUnmodifiableListImplementation 
Collections 
+ unmodifiableList(list : List<T>) : List<T> 
instantiates 
T
7 
Immutable Collections – Defense Copy Pattern – Part I 
● The strategy on which the discussed immutable collections are built is "forbidding mutating side effects". 
● But there exists a completely different approach: collections that can not be modified, but produce new collections! 
– Sorry? 
● Well, when a method is called that has a "mutating-name" (e.g. Add()), a copy of the mutated collection will be returned! 
– I.e. the original collection won't be changed! 
– We know this strategy from string types in Java and .Net and also from c-strings (const char*): 
● String-operations won't modify the original, but new strings with content different from the original string are returned. 
– This strategy is sometimes called the defense copy pattern.
; Lisp: Creates a list containing some ints: 
(let ((numbers '(1 2 3 4 5 6 7 8 9 ))) 
; Creates a new list from numbers having 42 appended: 
; >numbers2: {1, 2, 3, 4, 5, 6, 7, 8, 9, 42} 
; >numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} 
; Creates a new list from numbers having the value 3 removed: 
8 
Immutable Collections – Defense Copy Pattern – Part II 
● For .Net 4.5 and newer such types are available as extra NuGet package Microsoft.Collections.Immutable. 
– There (namespace System.Collections.Immutable) are ImmutableList, ImmutableDictionary, some interfaces to exploit the DIP etc.. 
● The instances of those collections are created with simple factories, i.e. those collections don't provide public ctors. 
// .Net/C#: Creates an immutable list containing some ints with the 
// simple factory ImmutableList.Create: 
IImmutableList<int> numbers = ImmutableList.Create(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); 
// Creates a new immutable list from numbers having the number 42 appended: 
IImmutableList<int> numbers2 = numbers.Add(42); 
// >numbers2: {1, 2, 3, 4, 5, 6, 7, 8, 9, 42}, numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} 
// Creates a another immutable list from numbers having the value 3 removed: 
IImmutableList<int> numbers3 = numbers.Remove(3, EqualityComparer<int>.Default); 
// >numbers3: {1, 2, 4, 5, 6, 7, 8, 9}, numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} 
(let ((numbers2 (append numbers '(42)))) 
(let ((numbers3 (remove 3 numbers))) 
; >numbers3: {1, 2, 4, 5, 6, 7, 8, 9} 
; >numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} 
))) 
– If we look closely, we'll notice, that numbers won't be modified! - E.g. numbers3 doesn't have the 42 at the end! 
● Well, the content of numbers is kept as defense copy, its content cannot be modified. Period! 
● This strategy is somehow taken directly from functional programming languages, where side effects are frowned upon. 
– Why is that useful? When we can't have side effects on collections, we can write thread safe code in a straight forward way! 
– The downside of this approach is that more memory for the defense copies is required. 
– It's another equation of applied computing: We get performance (thread-parallelization), but pay it with extra memory consumption!
Empty Collections – Part I 
● Often collections are used as return value of an algorithm. The usual result of failure is returning a "invalid" value like null: 
IList<int> result = GetNumbersFromUser(); 
// The returned input must be checked for nullity before accessing it! 
if (null != result) { 
9 
public static IList<int> GetNumbersFromUser() { 
IList<int> fromUser = new List<int>(); 
try { 
// Get input from user here and fill the list fromUser... 
} catch (Exception ex) { //... if something went wrong return null. 
return null; 
} return fromUser; 
} 
foreach (int item in result) { 
Console.WriteLine(item); 
} 
} 
– Checking the result for null every time after GetNumbersFromUser() was called is cumbersome and it could be forgotten! 
– Another idea is to return an empty collection as the result, then no checking for nullity is required: 
public static IList<int> GetNumbersFromUser() { 
IList<int> fromUser = new List<int>(); 
try { 
// Get input from user here and fill the list fromUser... 
} catch(Exception ex) { //... if something went wrong return an empty list. 
return new List<int>(0); 
} return fromUser; 
● What we've just encountered is called the null-object design pattern. 
– The idea is to return a genuine empty object instead of an invalid object, so that callers need no special treatment of results. 
} 
IList<int> result = GetNumbersFromUser(); 
// The returned input can just be iterated. No checking for "invalidity" is required! 
foreach(int item in result) { 
Console.WriteLine(item); 
}
10 
Empty Collections – Part II 
● Java supports the idea of empty collections and the null-object design pattern by Collections' simple factories: 
List<Integer> fromUser = new ArrayList<>(); 
try { 
// Get input from user here and fill the list fromUser... 
} catch (Exception ex) { //... if something went wrong return an empty list. 
return Collections.emptyList(); 
} return fromUser; 
– Besides emptyList() there exist similar simple factories producing other empty collections (Maps, Sets, Iterators etc.). 
– These simple factories produce null-objects that are unmodifiable! 
– The produced null-object of a specific simple factory is always identical. - Here the object Collection.EMPTY_LIST is always returned. 
● The .Net framework doesn't directly support null-objects to get empty collections. Instead Enumerable's static methods 
can be used: 
IList<int> fromUser = new List<int>(); 
try { 
// Get input from user here and fill the list fromUser... 
} catch(Exception ex) { //... if something went wrong return an empty list. 
return Enumerable.Empty<int>().ToList(); // uses System.Linq.Enumerable 
} return fromUser; 
– The method-call chain Empty().ToList() produces/materializes an empty list. - The resulting list is modifiable. 
– The methods ToDictionary() and ToArray() can be used to create empty collections the same way.
11 
● There are structures that are not exactly collections, but help solving collection-like problems. 
– Tuples are types, which are data containers, but not yet collections. 
● Tuples. 
– Originally tuples are taken from maths, where they represent an ordered and finite sequence of items. 
● E.g. the coordinates values of a spatial vector can be expressed as tuple: 
● a is represented as 3-tuple, sometimes also called triple, a 1-tuple can be 
⃗a=(2 
75 
) can be represented as a tuple like so: acomp=(2,7,5) 
called single or monad, a 2-tuple can be called pair or twin or couple or double, others are simply n-tuples. 
● The "items" of the tuple are called components: 2, 7, and 5 are the components of a. 
– Extra: In programming the count and the static types of the components is not restricted. Esp. components needn't to be numbers! 
● In .Net we can have up to seven components, more components are put into effect by setting tuples as rest component of a 7-tuple. 
● Using .Net Tuples: 
Tuples as Pseudo Collections – Part I 
// There exist several generic overloads for Tuples having different counts of components: 
public class Tuple<T1, T2> { /* pass */ } 
public class Tuple<T1, T2, T3> { /* pass */ } // etc. 
// Creating some tuples: 
Tuple<int, int, int> a = new Tuple<int, int, int>(2, 7, 5); // The representation of the spatial vector a. 
Tuple<int, string> twoTuple = Tuple.Create(2, "two"); // A couple using the simple factory Tuple.Create and type inference. 
Tuple<string, int, double> triple = Tuple.Create("three", 3, .7); // A triple. 
// Accessing a tuple's components: 
Console.WriteLine("couple's item1: {0} couple's item2: {1}", twoTuple.Item1, twoTuple.Item2); // Mind the fix property names Item1 and Item2! 
// >couple's item1: 2, couple's item2: two
Tuples as Pseudo Collections – Part II 
● Tuples have been added to .Net because the (then) new first class .Net language F# introduced tuples as genuine concept. 
12 
– F# provides integrated syntactical support for tuples, similar to the support of arrays in other languages: 
// Creating some tuples with F#' integrated syntax: 
let a = (2, 7, 5) // The representation of the spatial vector a. The type is inferred to (int * int * int). 
let twoTuple = (2, "two") // A couple. The inferred tuple type is (int * string). 
// Accessing a couple's components: 
printfn "couple's item1: %A couple's item2: %A" (fst twoTuple) (snd twoTuple) 
// >couple's item1: 2, couple's item2: "two" 
● Collections of Tuples are common sense: Why creating a UDT for car, if we can just use a Tuple as a "container"? 
Tuple<int, string>[] cars = new[] { // A car represented by tuples (int Horsepower * string Name) 
Tuple.Create(200, "500 Abarth Assetto Corse"), 
Tuple.Create(130, "Ford Focus 2.0"), 
Tuple.Create(55, "VW Kaffeemühle"), 
Tuple.Create(354, "Lotus Esprit V8"), 
Tuple.Create(112, "Alfa Romeo Giulia ti Super") 
}; 
– It should be underscored that the semantics of "car" is no longer present. Its abstraction was flattened into a (int * string) tuple. 
● A (int * string) tuple could also represent (int Phonenumber * string Name). 
● Java provides no dedicated UDTs to represent tuples, but those can be created easily.
Filling Collections with Data – .Net/C# 
● Many languages provide ways to fill collections with new objects in a concise and compact manner. Let's review those. 
13 
– We mainly discuss compact ways to instantiate objects in order to fill collections directly or even literally. 
● Anonymous types: Besides filling collections with tuples, C# allows filling collections with instances of anonymous types: 
Tuple<int, string>[] cars = new[] { // A car represented by tuples 
// (int Horsepower * string Name) 
Tuple.Create(200, "500 Abarth Assetto Corse"), 
Tuple.Create(130, "Ford Focus 2.0"), 
Tuple.Create(55, "VW Kaffeemühle"), 
Tuple.Create(354, "Lotus Esprit V8"), 
Tuple.Create(112, "Alfa Romeo Giulia ti Super") 
● Anonymous types as alternative to .Net Tuples: 
– Pro: anonymous types have richer semantics, because named properties can be used ad hoc. 
– Contra: It's needed to use type inference (var), which makes code more arcane. Instances can't be returned from or passed to methods. 
● However, we could use dynamic typing. 
}; 
var cars = new[] { // A car represented by instances of anonymous types 
// {int Horsepower, string Name} 
new { Horsepower = 200, Name = "500 Abarth Assetto Corse" }, 
new { Horsepower = 130, Name = "Ford Focus 2.0" }, 
new { Horsepower = 55, Name = "VW Kaffeemühle" }, 
new { Horsepower = 354, Name = "Lotus Esprit V8" }, 
new { Horsepower = 112, Name = "Alfa Romeo Giulia ti Super" } 
};
Filling Collections with Data – Groovy and JavaScript 
● Groovy allows defining lists of maps (associative collections). The maps act like bags of properties as fully blown objects: 
def cars = [ // A car represented by instances of maps 
// [Horsepower : Integer, Name : String] 
[ HorsePower : 200, Name : "500 Abarth Assetto Corse" ], 
[ HorsePower : 130, Name : "Ford Focus 2.0" ], 
[ HorsePower : 55, Name : "VW Kaffeemühle" ], 
[ HorsePower : 354, Name : "Lotus Esprit V8" ], 
[ HorsePower : 112, Name : "Alfa Romeo Giulia ti Super" ] 
] 
● In JavaScript, we have true dynamic typing, in which we don't need specific types. We can just write object literals directly. 
14 
– Here we have an array holding five object literals representing cars: 
var cars = [ // A car represented by object literals 
// {Horsepower, Name} 
{ HorsePower : 200, Name : "500 Abarth Assetto Corse" }, 
{ HorsePower : 130, Name : "Ford Focus 2.0" }, 
{ HorsePower : 55, Name : "VW Kaffeemühle" }, 
{ HorsePower : 354, Name : "Lotus Esprit V8" }, 
{ HorsePower : 112, Name : "Alfa Romeo Giulia ti Super" } 
] 
● Java does not yet provide simple means to freely define instances (to be used for filling collections). 
– Following the Java philosophy a suitable JVM language (like Scala or Groovy) should be used.
Filling Collections – do it in Bulk 
● Collections can also be created along with a bulk of data, which can yield performance benefits due to efficient capacitation: 
15 
– (Not all platforms apply capacity control on bulk operations!) 
// Java; instead of adding items to a list with a loop... 
List<Integer> numbers = new ArrayList<>(); 
for (int item : new int[]{1, 2, 3, 4}) { 
numbers.add(item); 
● Often collections can also be filled with items in bulk after creation: 
} 
// … the list could be initialized with another "ad hoc" collection like an array: 
List<Integer> numbers2 = new ArrayList<>(Arrays.asList(1, 2, 3, 4)); 
// C#; instead of adding items to a list with a collection initializer or loop... 
IList<int> numbers = new List<int>{1, 2, 3, 4}; 
IList<int> numbers2 = new List<int>(); 
foreach (int item in new []{1, 2, 3, 4}) { 
numbers2.Add(item); 
} 
// … the list could be initialized with another "ad hoc" collection like an array: 
IList<int> numbers3 = new List<int>(new []{1, 2, 3, 4}); 
// Java; adding a couple of items to a list in bulk: 
List<Integer> numbers = new ArrayList<>(); 
numbers.addAll(Arrays.asList(1, 2, 3, 4)) 
// Alternatively Collections.addAll() can be used (its usually faster): 
Collections.addAll(numbers, 1, 2, 3, 4); 
// C#; adding a couple of items to a list in bulk: 
List<int> numbers = new List<int>(); 
// (Mind that AddRange() isn't available via the interface IList!) 
numbers.AddRange(new []{1,2,3,4});
Collections abstracting Data Processing – Stack 
● There exist collections that directly represent the ways data is processed in computing whilst holding the data. 
– We'll discuss the collections stack and queue. 
– (The heap is also a collection of this category, but we'll ignore it in this course.) 
● The idea of a stack is to take the put-in items out in the reverse order. This principle is called Last-In-First-Out (LIFO). 
● E.g. assume that we want to put waypoints on a hike and we want to reach the waypoints again when we hike back. 
– After we hiked there, we get following stack of visited waypoints (we start on 0km and 25km was the last visited waypoint): 
waypoints 
25 
15 
3 
4 
2 
– When we hike back, we pick up the waypoints in the reverse order of visitation (we start on the last waypoint visited and drill down): 
waypoints 16 
● Now we'll put this into code. 
0 5 
25 
15 
0 5 
1 
2 
4 
1 
3
17 
Collections abstracting Data Processing – Stack – 
fundamental Operations 
● Let's discuss the .Net collection Stack: 
– The method Push() pushes items on the stack: 
// Create a Stack and push four waypoint km-marks on it: 
Stack<int> waypoints = new Stack<int>(4); 
waypoints.Push(0); 
waypoints.Push(5); 
waypoints.Push(15); 
waypoints.Push(25); 
– The method Pop() pops items from the stack (LIFO): 
int lastWaypoint = waypoints.Pop(); 
// >lastWaypoint evaluates to 25, because it was put in last 
– The method Peek() returns the last pushed item, but doesn't pop it from the stack. 
int penultimateWaypoint = waypoints.Peek(); 
// >penultimateWaypoint evaluates to 15, because it was put in penultimately 
– If Pop() or Peek() are applied on an empty Stack an InvalidOperationException will be thrown. 
25 
15 
waypoints 0 5 
● Stack collection types on other platforms: C++ STL provides std::stack (<stack>) and Java provides Stack.
Collections abstracting Data Processing – Queue 
● The idea of a queue is to take the put-in items out in the same order. This principle is called First-In-First-Out (FIFO). 
18 
● E.g. assume that we want to read emails in the order they receive the mailbox. 
– The emails are received in this order: 
"What an offer!..." 
"Honey, could you..." 
"Customer wants..." 
3 
1 
4 
– When we're going to read the emails we read them in the same order, in which they have been received: 
● Now we'll put this into code. 
"Dinner at 7pm..." mailbox 
2 
"What an offer!..." 
"Honey, could you..." 
"Customer wants..." 
3 
1 
"Dinner at 7pm..." mailbox 
4 
2
19 
Collections abstracting Data Processing – Queue – 
fundamental Operations 
● Let's discuss the .Net collection Queue: 
– The method Enqueue() enqueues items into the queue: 
// Create a Queue and enqueue four emails in receipt order: 
Queue<string> mailbox = new Queue<string>(4); 
mailbox.Enqueue("Dinner at 7pm..."); 
mailbox.Enqueue("Customer wants..."); 
mailbox.Enqueue("Honey, could you..."); 
mailbox.Enqueue("What an offer!..."); 
– The method Dequeue() dequeues items from the queue (FIFO): 
string firstEmail = mailbox.Dequeue(); 
// >firstEmail evaluates to "Dinner at 7pm...", because it was put in at first 
– The method Peek() returns the last enqueued item, but doesn't dequeue it from the queue. 
"What an offer!..." 
"Honey, could you..." 
"Customer wants..." 
string secondEmail = mailbox.Peek(); 
// >secondEmail evaluates to "Customer wants...", because it was put in at second 
"Dinner at 7pm..." 
– If Dequeue() or Peek() are applied on an empty Queue an InvalidOperationException will be thrown. 
mailbox 
● Queue collection types on other platforms: C++ STL provides std::queue/std::priority_queue (both in <queue>) and 
std::deque (<deque>). Among others, Java provides LinkedList as implementation of the interface Queue.
20 
Kung Fu beyond Collections – Part I 
● Up to now we've mentioned functional programming (fp) languages a lot in the context of collections. 
– The interesting point is that those languages deal with data in a special way: data is generally immutable after creation. 
– The lack of mutability, which is fundamental for, e.g. imperative languages, leads to fps having mighty features for data creation: 
● Support of immutability, list comprehensions, generic types, type inference. 
– The "main stream" languages are going to adopt or have already adopted these features as new language idioms. 
● Why are these adopting fp idioms? 
– The most important point is more productivity whilst programming. 
– A secondary aspect is that immutable types makes writing threadsafe a piece of cake. 
● Modern code should exploit the availability of parallel computing power today. 
● You should know or learn about these features! They are real game changers for programmers! 
● Let's rewrite an imperative code snippet that produces a new collection from a present collection.
Kung Fu beyond Collections – Part II 
● We have a list of numbers and we want to filter the odd numbers out to get only the even numbers, the classical way: 
// C# 
IList<int> numbers = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
IList<int> evenNumbers = new List<int>(); 
foreach(int number in numbers) { 
if (0 == number % 2) { 
evenNumbers.Add(number); 
} 
} 
– In both snippets we have a couple of statements, esp. a loop, a branch and adding elements to an initially empty collection, which 
will be filled. We already discussed this idea, when list comprehensions were presented: here we have sophisticated list compr. 
21 
● Now we'll rewrite the snippets using fp features of C# and Java (and Groovy and Scala): 
IList<int> numbers = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
IList<int> evenNumbers = ( from number in numbers 
where 0 == number % 2 
select number).ToList(); 
// >{2, 4, 6, 8} 
// Java 
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); 
List<Integer> evenNumbers = new ArrayList<>(); 
for(int number : numbers) { 
if (0 == number % 2) { 
evenNumbers.add(number); 
} 
} 
List<Integer> evenNumbers = 
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) 
.filter(number -> 0 == number%2) 
.collect(Collectors.toList()); 
// >{2, 4, 6, 8} 
// Groovy 
def numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
def evenNumbers = numbers.grep{0 == it % 2} 
// >[2, 4, 6, 8] 
// Scala 
def numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9) 
def evenNumbers = numbers.filter(number => 0 == number % 2) 
// >List(2, 4, 6, 8)
22 
Kung Fu beyond Collections – Part III 
● What we saw in action were .Net's LINQ and Java's streams API. 
// .Net's LINQ 
IList<int> numbers = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
IList<int> evenNumbers = (from number in numbers 
where 0 == number % 2 
select number).ToList(); 
// >{2, 4, 6, 8} 
– In both cases we don't have a couple of statements, but rather single expressions describing the results of the operations. 
– => LINQ and streams support a declarative programming style instead of an imperative programming style. 
● We'll not discuss LINQ and streams in this lecture, because there are some advanced idioms to understand: 
– Generic types 
– Type inference 
– Lambda expressions 
– Fluid interfaces and the "pipes and filters" architectural style 
// Java's streams 
List<Integer> evenNumbers = 
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) 
.filter(number -> 0 == number%2) 
.collect(Collectors.toList()); 
// >{2, 4, 6, 8}
23 
Thank you!

More Related Content

What's hot (19)

C++11 and 64-bit Issues
C++11 and 64-bit IssuesC++11 and 64-bit Issues
C++11 and 64-bit Issues
 
Headache from using mathematical software
Headache from using mathematical softwareHeadache from using mathematical software
Headache from using mathematical software
 
02. Primitive Data Types and Variables
02. Primitive Data Types and Variables02. Primitive Data Types and Variables
02. Primitive Data Types and Variables
 
Raspberry Pi - Lecture 5 Python for Raspberry Pi
Raspberry Pi - Lecture 5 Python for Raspberry PiRaspberry Pi - Lecture 5 Python for Raspberry Pi
Raspberry Pi - Lecture 5 Python for Raspberry Pi
 
Lecture 10 compiler i
Lecture 10 compiler iLecture 10 compiler i
Lecture 10 compiler i
 
Intake 38 12
Intake 38 12Intake 38 12
Intake 38 12
 
06.Loops
06.Loops06.Loops
06.Loops
 
Java 8
Java 8Java 8
Java 8
 
Introduction to matlab
Introduction to matlabIntroduction to matlab
Introduction to matlab
 
Introduction to c++
Introduction to c++Introduction to c++
Introduction to c++
 
Computer Science Assignment Help
Computer Science Assignment HelpComputer Science Assignment Help
Computer Science Assignment Help
 
Python for Beginners(v3)
Python for Beginners(v3)Python for Beginners(v3)
Python for Beginners(v3)
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Lambda Expressions in Java
Lambda Expressions in JavaLambda Expressions in Java
Lambda Expressions in Java
 
Python for Data Science
Python for Data SciencePython for Data Science
Python for Data Science
 
13 Strings and Text Processing
13 Strings and Text Processing13 Strings and Text Processing
13 Strings and Text Processing
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
10. Recursion
10. Recursion10. Recursion
10. Recursion
 
Cpp Homework Help
Cpp Homework Help Cpp Homework Help
Cpp Homework Help
 

Similar to (6) collections algorithms

(2) collections algorithms
(2) collections algorithms(2) collections algorithms
(2) collections algorithmsNico Ludwig
 
(4) collections algorithms
(4) collections algorithms(4) collections algorithms
(4) collections algorithmsNico Ludwig
 
Visual Programing basic lectures 7.pptx
Visual Programing basic lectures  7.pptxVisual Programing basic lectures  7.pptx
Visual Programing basic lectures 7.pptxMrhaider4
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And AnswerJagan Mohan Bishoyi
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answerlavparmar007
 
(4) collections algorithms
(4) collections algorithms(4) collections algorithms
(4) collections algorithmsNico Ludwig
 
Synapseindia reviews.odp.
Synapseindia reviews.odp.Synapseindia reviews.odp.
Synapseindia reviews.odp.Tarunsingh198
 
Lecture_01.2.pptx
Lecture_01.2.pptxLecture_01.2.pptx
Lecture_01.2.pptxRockyIslam5
 
Javase5generics
Javase5genericsJavase5generics
Javase5genericsimypraz
 
arrays-120712074248-phpapp01
arrays-120712074248-phpapp01arrays-120712074248-phpapp01
arrays-120712074248-phpapp01Abdul Samee
 
Abstract Data Types (a) Explain briefly what is meant by the ter.pdf
Abstract Data Types (a) Explain briefly what is meant by the ter.pdfAbstract Data Types (a) Explain briefly what is meant by the ter.pdf
Abstract Data Types (a) Explain briefly what is meant by the ter.pdfkarymadelaneyrenne19
 
Java tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenJava tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenGraham Royce
 
Java Tutorial | My Heart
Java Tutorial | My HeartJava Tutorial | My Heart
Java Tutorial | My HeartBui Kiet
 

Similar to (6) collections algorithms (20)

(2) collections algorithms
(2) collections algorithms(2) collections algorithms
(2) collections algorithms
 
(4) collections algorithms
(4) collections algorithms(4) collections algorithms
(4) collections algorithms
 
Beginning linq
Beginning linqBeginning linq
Beginning linq
 
Visual Programing basic lectures 7.pptx
Visual Programing basic lectures  7.pptxVisual Programing basic lectures  7.pptx
Visual Programing basic lectures 7.pptx
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And Answer
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
(4) collections algorithms
(4) collections algorithms(4) collections algorithms
(4) collections algorithms
 
Collections
CollectionsCollections
Collections
 
Synapseindia reviews.odp.
Synapseindia reviews.odp.Synapseindia reviews.odp.
Synapseindia reviews.odp.
 
Lecture_01.2.pptx
Lecture_01.2.pptxLecture_01.2.pptx
Lecture_01.2.pptx
 
Javase5generics
Javase5genericsJavase5generics
Javase5generics
 
arrays-120712074248-phpapp01
arrays-120712074248-phpapp01arrays-120712074248-phpapp01
arrays-120712074248-phpapp01
 
Abstract Data Types (a) Explain briefly what is meant by the ter.pdf
Abstract Data Types (a) Explain briefly what is meant by the ter.pdfAbstract Data Types (a) Explain briefly what is meant by the ter.pdf
Abstract Data Types (a) Explain briefly what is meant by the ter.pdf
 
Java tut1
Java tut1Java tut1
Java tut1
 
Java tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo CahersiveenJava tut1 Coderdojo Cahersiveen
Java tut1 Coderdojo Cahersiveen
 
Javatut1
Javatut1 Javatut1
Javatut1
 
Java tut1
Java tut1Java tut1
Java tut1
 
Java Tutorial
Java TutorialJava Tutorial
Java Tutorial
 
C sharp chap6
C sharp chap6C sharp chap6
C sharp chap6
 
Java Tutorial | My Heart
Java Tutorial | My HeartJava Tutorial | My Heart
Java Tutorial | My Heart
 

More from Nico Ludwig

Grundkurs fuer excel_part_v
Grundkurs fuer excel_part_vGrundkurs fuer excel_part_v
Grundkurs fuer excel_part_vNico Ludwig
 
Grundkurs fuer excel_part_iv
Grundkurs fuer excel_part_ivGrundkurs fuer excel_part_iv
Grundkurs fuer excel_part_ivNico Ludwig
 
Grundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iiiGrundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iiiNico Ludwig
 
Grundkurs fuer excel_part_ii
Grundkurs fuer excel_part_iiGrundkurs fuer excel_part_ii
Grundkurs fuer excel_part_iiNico Ludwig
 
Grundkurs fuer excel_part_i
Grundkurs fuer excel_part_iGrundkurs fuer excel_part_i
Grundkurs fuer excel_part_iNico Ludwig
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivityNico Ludwig
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivityNico Ludwig
 
New c sharp4_features_part_vi
New c sharp4_features_part_viNew c sharp4_features_part_vi
New c sharp4_features_part_viNico Ludwig
 
New c sharp4_features_part_v
New c sharp4_features_part_vNew c sharp4_features_part_v
New c sharp4_features_part_vNico Ludwig
 
New c sharp4_features_part_iv
New c sharp4_features_part_ivNew c sharp4_features_part_iv
New c sharp4_features_part_ivNico Ludwig
 
New c sharp4_features_part_iii
New c sharp4_features_part_iiiNew c sharp4_features_part_iii
New c sharp4_features_part_iiiNico Ludwig
 
New c sharp4_features_part_ii
New c sharp4_features_part_iiNew c sharp4_features_part_ii
New c sharp4_features_part_iiNico Ludwig
 
New c sharp4_features_part_i
New c sharp4_features_part_iNew c sharp4_features_part_i
New c sharp4_features_part_iNico Ludwig
 
New c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_vNew c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_vNico Ludwig
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNico Ludwig
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNico Ludwig
 
New c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_iiNew c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_iiNico Ludwig
 
New c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_iNew c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_iNico Ludwig
 

More from Nico Ludwig (20)

Grundkurs fuer excel_part_v
Grundkurs fuer excel_part_vGrundkurs fuer excel_part_v
Grundkurs fuer excel_part_v
 
Grundkurs fuer excel_part_iv
Grundkurs fuer excel_part_ivGrundkurs fuer excel_part_iv
Grundkurs fuer excel_part_iv
 
Grundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iiiGrundkurs fuer excel_part_iii
Grundkurs fuer excel_part_iii
 
Grundkurs fuer excel_part_ii
Grundkurs fuer excel_part_iiGrundkurs fuer excel_part_ii
Grundkurs fuer excel_part_ii
 
Grundkurs fuer excel_part_i
Grundkurs fuer excel_part_iGrundkurs fuer excel_part_i
Grundkurs fuer excel_part_i
 
(2) gui drawing
(2) gui drawing(2) gui drawing
(2) gui drawing
 
(2) gui drawing
(2) gui drawing(2) gui drawing
(2) gui drawing
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivity
 
(1) gui history_of_interactivity
(1) gui history_of_interactivity(1) gui history_of_interactivity
(1) gui history_of_interactivity
 
New c sharp4_features_part_vi
New c sharp4_features_part_viNew c sharp4_features_part_vi
New c sharp4_features_part_vi
 
New c sharp4_features_part_v
New c sharp4_features_part_vNew c sharp4_features_part_v
New c sharp4_features_part_v
 
New c sharp4_features_part_iv
New c sharp4_features_part_ivNew c sharp4_features_part_iv
New c sharp4_features_part_iv
 
New c sharp4_features_part_iii
New c sharp4_features_part_iiiNew c sharp4_features_part_iii
New c sharp4_features_part_iii
 
New c sharp4_features_part_ii
New c sharp4_features_part_iiNew c sharp4_features_part_ii
New c sharp4_features_part_ii
 
New c sharp4_features_part_i
New c sharp4_features_part_iNew c sharp4_features_part_i
New c sharp4_features_part_i
 
New c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_vNew c sharp3_features_(linq)_part_v
New c sharp3_features_(linq)_part_v
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_iv
 
New c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_ivNew c sharp3_features_(linq)_part_iv
New c sharp3_features_(linq)_part_iv
 
New c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_iiNew c sharp3_features_(linq)_part_ii
New c sharp3_features_(linq)_part_ii
 
New c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_iNew c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_i
 

Recently uploaded

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 

Recently uploaded (20)

Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 

(6) collections algorithms

  • 1. Collections – Part VI Nico Ludwig (@ersatzteilchen)
  • 2. 2 ● Collections – Part VI TOC – Producing Collection Objects – Immutable Collections and defense Copies – Empty Collections – Tuples as pseudo Collections – Filling Collections with structured Data – Collections abstracting Data Processing: Stack and Queue – Kung Fu beyond Collections: .Net's LINQ and Java's Streams
  • 3. Producing Collection Objects ● Java: We already discussed Collections' simple factories producing collections in Java, but there exist more of these: 3 – The class Arrays provides similar simple factories: the method asList() produces an unmodifiable List from the passed array: public static void main(String[] args) throws Exception { List<String> arguments = Arrays.asList(args); // Creates an unmodifiable List from an array. } – Because asList() accepts a variable count of arguments, we can directly pass some values, instead of a first class array: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); // Creates a List from a couple of arguments. ● .Net: There exist many means to produce collections through extension methods from the System.Linq namespace. – E.g. producing a List from an array with the extension method ToList(): public static void Main(string[] args) { IList<string> arguments = args.ToList(); // Creates a List from an array. } – .Net's class Enumerable provides the methods Range() and Repeat() (i.e. simple factories) to produce respective sequences. ● The method-call chain with ToList() produces/materializes the lists from the sequences. - The resulting list is modifiable. IList<int> numbers = Enumerable.Range(1, 6).ToList(); // Creates a List of integers from 1 to 6 inclusively. IList<int> sixCopiesOf42 = Enumerable.Repeat(42, 6).ToList(); // Creates a List containing six copies of the integer 42.
  • 4. 4 Immutable Collections – Part I ● Immutability of objects is a relevant topic meanwhile to write robust applications. How is it supported for collections? ● In C++, container objects can be idiomatically be set as const, then non-const member functions are no longer callable: // Defines a const vector containing some ints: const std::vector<int> numbers{1, 2, 3, 4, 5, 6}; // After the const vector was created it cannot be modified: numbers.push_back(7); // Results in a compile time error! // But reading is no problem: int value = numbers[0]; – The objects managed by a const std::vector cannot be modified as well! This is called const-correctness in C++. – (This idiomatic usage of const objects in C++ requires no further explanation.) ● In the COCOA framework there exist mutable and immutable collections separately: // Defines an immutable NSArray containing some ints: NSArray* numbers = @[@1, @2, @3, @4, @5, @6]; // NSArray does not expose any methods that could modify numbers, therefor we // have to create an NSMutableArray from numbers: NSMutableArray* mutableNumbers = [NSMutableArray arrayWithArray:numbers]; // NSMutableArray provides methods to modify the collection: [mutableNumbers addObject:@7]; – NSMutableArray inherits from NSArray, this idea is used for other COCOA collections as well.
  • 5. Immutable Collections – Part II // Defines a list containing some ints: IList<int> numbers = new List<int>{1, 2, 3, 4, 5, 6 }; // The mutable IList<int> will be wrapped by an immutable ReadOnlyCollection<int> (from the namespace System.Collections.ObjectModel): ReadOnlyCollection<int> readOnlyNumbers = new ReadOnlyCollection<int>(numbers); // ReadOnlyCollection<T> implements IList<T> so that it can partake in APIs requiring objects exposing that interface. // But IList<T> is implemented explicitly, so potentially mutable methods can not be directly called: readOnlyNumbers.Add(7); // Results in a compile time error. // If ReadOnlyCollection<T> is accessed via the IList<T> interface, calling potentially mutable methods will throw a NotSupportedException. IList<int> readOnlyNumbersAsList = readOnlyNumbers; readOnlyNumbersAsList.Add(7); // Results in a run time error: NotSupportedException will be thrown. 5 ● The .Net framework follows another principle to provide immutability: wrapping. – Wrapping means, that a present instance is wrapped into another object in order to adopt another interface or to get another behavior. – Alternatively List<T>'s method AsReadOnly() can be used, which directly returns readonly wrappers. – The idea of wrapping is used for ReadOnlyDictionary as well. – Objects implementing ICollection<T> can be checked if these are readonly with the property ICollection<T>.IsReadOnly. ● The design pattern we've encountered here is called wrapper or adapter. <<interface>> IList ReadOnlyCollection wraps implements T T // Directly create a ReadOnlyCollection<int> from a List<int> ReadOnlyCollection<int> readOnlyNumbers2 = new List<int>{1, 2, 3, 4, 5, 6 }.AsReadOnly();
  • 6. 6 Immutable Collections – Part III ● Java does also apply the wrapper principle to provide immutability. – Java hides the wrapper type completely from the caller, but exposes an unmodifiable object implementing a collection interface. – The unmodifiable implementation is somehow internally instantiated by the simple factory Collections.unmodifiable...(). // Defines a list containing some ints: List<Integer> numbers = new ArrayList<>(Arrays.<Integer>asList(1, 2, 3, 4, 5, 6)); // The mutable List<int> will be wrapped by an unmodifiable List<int>: List<Integer> readOnlyNumbers = Collections.unmodifiableList(numbers); // Calling the simple factory. // readOnlyNumbers' potentially mutable methods can be called, but these calls will throw UnsupportedOperationExceptions. readOnlyNumbers.add(7); // Results in a run time error: UnsupportedOperationException will be thrown. ● Java: More simple factories can be found in the class Collections as static methods (unmodifiableSet(), unmodifiableMap()). – The return type of all of these simple factories are just interface types, the unmodifiable implementations are always hidden. – So the UML diagram of the relations between the contributing types looks like so: <<interface>> List exposes implements HiddenUnmodifiableListImplementation Collections + unmodifiableList(list : List<T>) : List<T> instantiates T
  • 7. 7 Immutable Collections – Defense Copy Pattern – Part I ● The strategy on which the discussed immutable collections are built is "forbidding mutating side effects". ● But there exists a completely different approach: collections that can not be modified, but produce new collections! – Sorry? ● Well, when a method is called that has a "mutating-name" (e.g. Add()), a copy of the mutated collection will be returned! – I.e. the original collection won't be changed! – We know this strategy from string types in Java and .Net and also from c-strings (const char*): ● String-operations won't modify the original, but new strings with content different from the original string are returned. – This strategy is sometimes called the defense copy pattern.
  • 8. ; Lisp: Creates a list containing some ints: (let ((numbers '(1 2 3 4 5 6 7 8 9 ))) ; Creates a new list from numbers having 42 appended: ; >numbers2: {1, 2, 3, 4, 5, 6, 7, 8, 9, 42} ; >numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} ; Creates a new list from numbers having the value 3 removed: 8 Immutable Collections – Defense Copy Pattern – Part II ● For .Net 4.5 and newer such types are available as extra NuGet package Microsoft.Collections.Immutable. – There (namespace System.Collections.Immutable) are ImmutableList, ImmutableDictionary, some interfaces to exploit the DIP etc.. ● The instances of those collections are created with simple factories, i.e. those collections don't provide public ctors. // .Net/C#: Creates an immutable list containing some ints with the // simple factory ImmutableList.Create: IImmutableList<int> numbers = ImmutableList.Create(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); // Creates a new immutable list from numbers having the number 42 appended: IImmutableList<int> numbers2 = numbers.Add(42); // >numbers2: {1, 2, 3, 4, 5, 6, 7, 8, 9, 42}, numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} // Creates a another immutable list from numbers having the value 3 removed: IImmutableList<int> numbers3 = numbers.Remove(3, EqualityComparer<int>.Default); // >numbers3: {1, 2, 4, 5, 6, 7, 8, 9}, numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} (let ((numbers2 (append numbers '(42)))) (let ((numbers3 (remove 3 numbers))) ; >numbers3: {1, 2, 4, 5, 6, 7, 8, 9} ; >numbers: {1, 2, 3, 4, 5, 6, 7, 8, 9} ))) – If we look closely, we'll notice, that numbers won't be modified! - E.g. numbers3 doesn't have the 42 at the end! ● Well, the content of numbers is kept as defense copy, its content cannot be modified. Period! ● This strategy is somehow taken directly from functional programming languages, where side effects are frowned upon. – Why is that useful? When we can't have side effects on collections, we can write thread safe code in a straight forward way! – The downside of this approach is that more memory for the defense copies is required. – It's another equation of applied computing: We get performance (thread-parallelization), but pay it with extra memory consumption!
  • 9. Empty Collections – Part I ● Often collections are used as return value of an algorithm. The usual result of failure is returning a "invalid" value like null: IList<int> result = GetNumbersFromUser(); // The returned input must be checked for nullity before accessing it! if (null != result) { 9 public static IList<int> GetNumbersFromUser() { IList<int> fromUser = new List<int>(); try { // Get input from user here and fill the list fromUser... } catch (Exception ex) { //... if something went wrong return null. return null; } return fromUser; } foreach (int item in result) { Console.WriteLine(item); } } – Checking the result for null every time after GetNumbersFromUser() was called is cumbersome and it could be forgotten! – Another idea is to return an empty collection as the result, then no checking for nullity is required: public static IList<int> GetNumbersFromUser() { IList<int> fromUser = new List<int>(); try { // Get input from user here and fill the list fromUser... } catch(Exception ex) { //... if something went wrong return an empty list. return new List<int>(0); } return fromUser; ● What we've just encountered is called the null-object design pattern. – The idea is to return a genuine empty object instead of an invalid object, so that callers need no special treatment of results. } IList<int> result = GetNumbersFromUser(); // The returned input can just be iterated. No checking for "invalidity" is required! foreach(int item in result) { Console.WriteLine(item); }
  • 10. 10 Empty Collections – Part II ● Java supports the idea of empty collections and the null-object design pattern by Collections' simple factories: List<Integer> fromUser = new ArrayList<>(); try { // Get input from user here and fill the list fromUser... } catch (Exception ex) { //... if something went wrong return an empty list. return Collections.emptyList(); } return fromUser; – Besides emptyList() there exist similar simple factories producing other empty collections (Maps, Sets, Iterators etc.). – These simple factories produce null-objects that are unmodifiable! – The produced null-object of a specific simple factory is always identical. - Here the object Collection.EMPTY_LIST is always returned. ● The .Net framework doesn't directly support null-objects to get empty collections. Instead Enumerable's static methods can be used: IList<int> fromUser = new List<int>(); try { // Get input from user here and fill the list fromUser... } catch(Exception ex) { //... if something went wrong return an empty list. return Enumerable.Empty<int>().ToList(); // uses System.Linq.Enumerable } return fromUser; – The method-call chain Empty().ToList() produces/materializes an empty list. - The resulting list is modifiable. – The methods ToDictionary() and ToArray() can be used to create empty collections the same way.
  • 11. 11 ● There are structures that are not exactly collections, but help solving collection-like problems. – Tuples are types, which are data containers, but not yet collections. ● Tuples. – Originally tuples are taken from maths, where they represent an ordered and finite sequence of items. ● E.g. the coordinates values of a spatial vector can be expressed as tuple: ● a is represented as 3-tuple, sometimes also called triple, a 1-tuple can be ⃗a=(2 75 ) can be represented as a tuple like so: acomp=(2,7,5) called single or monad, a 2-tuple can be called pair or twin or couple or double, others are simply n-tuples. ● The "items" of the tuple are called components: 2, 7, and 5 are the components of a. – Extra: In programming the count and the static types of the components is not restricted. Esp. components needn't to be numbers! ● In .Net we can have up to seven components, more components are put into effect by setting tuples as rest component of a 7-tuple. ● Using .Net Tuples: Tuples as Pseudo Collections – Part I // There exist several generic overloads for Tuples having different counts of components: public class Tuple<T1, T2> { /* pass */ } public class Tuple<T1, T2, T3> { /* pass */ } // etc. // Creating some tuples: Tuple<int, int, int> a = new Tuple<int, int, int>(2, 7, 5); // The representation of the spatial vector a. Tuple<int, string> twoTuple = Tuple.Create(2, "two"); // A couple using the simple factory Tuple.Create and type inference. Tuple<string, int, double> triple = Tuple.Create("three", 3, .7); // A triple. // Accessing a tuple's components: Console.WriteLine("couple's item1: {0} couple's item2: {1}", twoTuple.Item1, twoTuple.Item2); // Mind the fix property names Item1 and Item2! // >couple's item1: 2, couple's item2: two
  • 12. Tuples as Pseudo Collections – Part II ● Tuples have been added to .Net because the (then) new first class .Net language F# introduced tuples as genuine concept. 12 – F# provides integrated syntactical support for tuples, similar to the support of arrays in other languages: // Creating some tuples with F#' integrated syntax: let a = (2, 7, 5) // The representation of the spatial vector a. The type is inferred to (int * int * int). let twoTuple = (2, "two") // A couple. The inferred tuple type is (int * string). // Accessing a couple's components: printfn "couple's item1: %A couple's item2: %A" (fst twoTuple) (snd twoTuple) // >couple's item1: 2, couple's item2: "two" ● Collections of Tuples are common sense: Why creating a UDT for car, if we can just use a Tuple as a "container"? Tuple<int, string>[] cars = new[] { // A car represented by tuples (int Horsepower * string Name) Tuple.Create(200, "500 Abarth Assetto Corse"), Tuple.Create(130, "Ford Focus 2.0"), Tuple.Create(55, "VW Kaffeemühle"), Tuple.Create(354, "Lotus Esprit V8"), Tuple.Create(112, "Alfa Romeo Giulia ti Super") }; – It should be underscored that the semantics of "car" is no longer present. Its abstraction was flattened into a (int * string) tuple. ● A (int * string) tuple could also represent (int Phonenumber * string Name). ● Java provides no dedicated UDTs to represent tuples, but those can be created easily.
  • 13. Filling Collections with Data – .Net/C# ● Many languages provide ways to fill collections with new objects in a concise and compact manner. Let's review those. 13 – We mainly discuss compact ways to instantiate objects in order to fill collections directly or even literally. ● Anonymous types: Besides filling collections with tuples, C# allows filling collections with instances of anonymous types: Tuple<int, string>[] cars = new[] { // A car represented by tuples // (int Horsepower * string Name) Tuple.Create(200, "500 Abarth Assetto Corse"), Tuple.Create(130, "Ford Focus 2.0"), Tuple.Create(55, "VW Kaffeemühle"), Tuple.Create(354, "Lotus Esprit V8"), Tuple.Create(112, "Alfa Romeo Giulia ti Super") ● Anonymous types as alternative to .Net Tuples: – Pro: anonymous types have richer semantics, because named properties can be used ad hoc. – Contra: It's needed to use type inference (var), which makes code more arcane. Instances can't be returned from or passed to methods. ● However, we could use dynamic typing. }; var cars = new[] { // A car represented by instances of anonymous types // {int Horsepower, string Name} new { Horsepower = 200, Name = "500 Abarth Assetto Corse" }, new { Horsepower = 130, Name = "Ford Focus 2.0" }, new { Horsepower = 55, Name = "VW Kaffeemühle" }, new { Horsepower = 354, Name = "Lotus Esprit V8" }, new { Horsepower = 112, Name = "Alfa Romeo Giulia ti Super" } };
  • 14. Filling Collections with Data – Groovy and JavaScript ● Groovy allows defining lists of maps (associative collections). The maps act like bags of properties as fully blown objects: def cars = [ // A car represented by instances of maps // [Horsepower : Integer, Name : String] [ HorsePower : 200, Name : "500 Abarth Assetto Corse" ], [ HorsePower : 130, Name : "Ford Focus 2.0" ], [ HorsePower : 55, Name : "VW Kaffeemühle" ], [ HorsePower : 354, Name : "Lotus Esprit V8" ], [ HorsePower : 112, Name : "Alfa Romeo Giulia ti Super" ] ] ● In JavaScript, we have true dynamic typing, in which we don't need specific types. We can just write object literals directly. 14 – Here we have an array holding five object literals representing cars: var cars = [ // A car represented by object literals // {Horsepower, Name} { HorsePower : 200, Name : "500 Abarth Assetto Corse" }, { HorsePower : 130, Name : "Ford Focus 2.0" }, { HorsePower : 55, Name : "VW Kaffeemühle" }, { HorsePower : 354, Name : "Lotus Esprit V8" }, { HorsePower : 112, Name : "Alfa Romeo Giulia ti Super" } ] ● Java does not yet provide simple means to freely define instances (to be used for filling collections). – Following the Java philosophy a suitable JVM language (like Scala or Groovy) should be used.
  • 15. Filling Collections – do it in Bulk ● Collections can also be created along with a bulk of data, which can yield performance benefits due to efficient capacitation: 15 – (Not all platforms apply capacity control on bulk operations!) // Java; instead of adding items to a list with a loop... List<Integer> numbers = new ArrayList<>(); for (int item : new int[]{1, 2, 3, 4}) { numbers.add(item); ● Often collections can also be filled with items in bulk after creation: } // … the list could be initialized with another "ad hoc" collection like an array: List<Integer> numbers2 = new ArrayList<>(Arrays.asList(1, 2, 3, 4)); // C#; instead of adding items to a list with a collection initializer or loop... IList<int> numbers = new List<int>{1, 2, 3, 4}; IList<int> numbers2 = new List<int>(); foreach (int item in new []{1, 2, 3, 4}) { numbers2.Add(item); } // … the list could be initialized with another "ad hoc" collection like an array: IList<int> numbers3 = new List<int>(new []{1, 2, 3, 4}); // Java; adding a couple of items to a list in bulk: List<Integer> numbers = new ArrayList<>(); numbers.addAll(Arrays.asList(1, 2, 3, 4)) // Alternatively Collections.addAll() can be used (its usually faster): Collections.addAll(numbers, 1, 2, 3, 4); // C#; adding a couple of items to a list in bulk: List<int> numbers = new List<int>(); // (Mind that AddRange() isn't available via the interface IList!) numbers.AddRange(new []{1,2,3,4});
  • 16. Collections abstracting Data Processing – Stack ● There exist collections that directly represent the ways data is processed in computing whilst holding the data. – We'll discuss the collections stack and queue. – (The heap is also a collection of this category, but we'll ignore it in this course.) ● The idea of a stack is to take the put-in items out in the reverse order. This principle is called Last-In-First-Out (LIFO). ● E.g. assume that we want to put waypoints on a hike and we want to reach the waypoints again when we hike back. – After we hiked there, we get following stack of visited waypoints (we start on 0km and 25km was the last visited waypoint): waypoints 25 15 3 4 2 – When we hike back, we pick up the waypoints in the reverse order of visitation (we start on the last waypoint visited and drill down): waypoints 16 ● Now we'll put this into code. 0 5 25 15 0 5 1 2 4 1 3
  • 17. 17 Collections abstracting Data Processing – Stack – fundamental Operations ● Let's discuss the .Net collection Stack: – The method Push() pushes items on the stack: // Create a Stack and push four waypoint km-marks on it: Stack<int> waypoints = new Stack<int>(4); waypoints.Push(0); waypoints.Push(5); waypoints.Push(15); waypoints.Push(25); – The method Pop() pops items from the stack (LIFO): int lastWaypoint = waypoints.Pop(); // >lastWaypoint evaluates to 25, because it was put in last – The method Peek() returns the last pushed item, but doesn't pop it from the stack. int penultimateWaypoint = waypoints.Peek(); // >penultimateWaypoint evaluates to 15, because it was put in penultimately – If Pop() or Peek() are applied on an empty Stack an InvalidOperationException will be thrown. 25 15 waypoints 0 5 ● Stack collection types on other platforms: C++ STL provides std::stack (<stack>) and Java provides Stack.
  • 18. Collections abstracting Data Processing – Queue ● The idea of a queue is to take the put-in items out in the same order. This principle is called First-In-First-Out (FIFO). 18 ● E.g. assume that we want to read emails in the order they receive the mailbox. – The emails are received in this order: "What an offer!..." "Honey, could you..." "Customer wants..." 3 1 4 – When we're going to read the emails we read them in the same order, in which they have been received: ● Now we'll put this into code. "Dinner at 7pm..." mailbox 2 "What an offer!..." "Honey, could you..." "Customer wants..." 3 1 "Dinner at 7pm..." mailbox 4 2
  • 19. 19 Collections abstracting Data Processing – Queue – fundamental Operations ● Let's discuss the .Net collection Queue: – The method Enqueue() enqueues items into the queue: // Create a Queue and enqueue four emails in receipt order: Queue<string> mailbox = new Queue<string>(4); mailbox.Enqueue("Dinner at 7pm..."); mailbox.Enqueue("Customer wants..."); mailbox.Enqueue("Honey, could you..."); mailbox.Enqueue("What an offer!..."); – The method Dequeue() dequeues items from the queue (FIFO): string firstEmail = mailbox.Dequeue(); // >firstEmail evaluates to "Dinner at 7pm...", because it was put in at first – The method Peek() returns the last enqueued item, but doesn't dequeue it from the queue. "What an offer!..." "Honey, could you..." "Customer wants..." string secondEmail = mailbox.Peek(); // >secondEmail evaluates to "Customer wants...", because it was put in at second "Dinner at 7pm..." – If Dequeue() or Peek() are applied on an empty Queue an InvalidOperationException will be thrown. mailbox ● Queue collection types on other platforms: C++ STL provides std::queue/std::priority_queue (both in <queue>) and std::deque (<deque>). Among others, Java provides LinkedList as implementation of the interface Queue.
  • 20. 20 Kung Fu beyond Collections – Part I ● Up to now we've mentioned functional programming (fp) languages a lot in the context of collections. – The interesting point is that those languages deal with data in a special way: data is generally immutable after creation. – The lack of mutability, which is fundamental for, e.g. imperative languages, leads to fps having mighty features for data creation: ● Support of immutability, list comprehensions, generic types, type inference. – The "main stream" languages are going to adopt or have already adopted these features as new language idioms. ● Why are these adopting fp idioms? – The most important point is more productivity whilst programming. – A secondary aspect is that immutable types makes writing threadsafe a piece of cake. ● Modern code should exploit the availability of parallel computing power today. ● You should know or learn about these features! They are real game changers for programmers! ● Let's rewrite an imperative code snippet that produces a new collection from a present collection.
  • 21. Kung Fu beyond Collections – Part II ● We have a list of numbers and we want to filter the odd numbers out to get only the even numbers, the classical way: // C# IList<int> numbers = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; IList<int> evenNumbers = new List<int>(); foreach(int number in numbers) { if (0 == number % 2) { evenNumbers.Add(number); } } – In both snippets we have a couple of statements, esp. a loop, a branch and adding elements to an initially empty collection, which will be filled. We already discussed this idea, when list comprehensions were presented: here we have sophisticated list compr. 21 ● Now we'll rewrite the snippets using fp features of C# and Java (and Groovy and Scala): IList<int> numbers = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; IList<int> evenNumbers = ( from number in numbers where 0 == number % 2 select number).ToList(); // >{2, 4, 6, 8} // Java List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); List<Integer> evenNumbers = new ArrayList<>(); for(int number : numbers) { if (0 == number % 2) { evenNumbers.add(number); } } List<Integer> evenNumbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) .filter(number -> 0 == number%2) .collect(Collectors.toList()); // >{2, 4, 6, 8} // Groovy def numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] def evenNumbers = numbers.grep{0 == it % 2} // >[2, 4, 6, 8] // Scala def numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9) def evenNumbers = numbers.filter(number => 0 == number % 2) // >List(2, 4, 6, 8)
  • 22. 22 Kung Fu beyond Collections – Part III ● What we saw in action were .Net's LINQ and Java's streams API. // .Net's LINQ IList<int> numbers = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; IList<int> evenNumbers = (from number in numbers where 0 == number % 2 select number).ToList(); // >{2, 4, 6, 8} – In both cases we don't have a couple of statements, but rather single expressions describing the results of the operations. – => LINQ and streams support a declarative programming style instead of an imperative programming style. ● We'll not discuss LINQ and streams in this lecture, because there are some advanced idioms to understand: – Generic types – Type inference – Lambda expressions – Fluid interfaces and the "pipes and filters" architectural style // Java's streams List<Integer> evenNumbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9) .filter(number -> 0 == number%2) .collect(Collectors.toList()); // >{2, 4, 6, 8}

Editor's Notes

  1. Immutable collections are very relevant to write threadsafe code.
  2. (Java&amp;apos;s class Collections provides many useful simple factories.)
  3. Lists in F# are also immutable, one can only create new lists having different content from the original lists. On the other hand F# does have an extra ugly syntax for array-creation, -accessing and -manipulation (uglier than the list syntax), which are mutable! So, F# clearly states immutable collections (i.e. F# lists) being more primary than arrays! It should be mentioned that memory management of fp languages is very sophisticated. Esp. during processing lists many new lists are generated, because lists are immutable; all the remaining superfluous lists need to be freed from memory. Therefor fp languages/runtimes were the first systems introducing garbage collection. Mind that the general ways of processing lists and also the memory considerations are equivalent to those of processing strings in Java and .Net, where strings are immutable (lists of characters). The Java Development Kit (JDK) does not provide collections like ImmutableXXX. But such collections can be retrieved from Google (package com.google.common.collect).
  4. Java: it&amp;apos;s recommended to use Collections.emptyList() instead of Collections.EMPTY_LIST! Collections.EMPTY_LIST is just a raw type, whereas with Collections.emptyList() the compiler can infer the correct type and the code will be type safe.
  5. Java&amp;apos;s Collections.addAll() is faster than Collection.addAll() because the latter creates a redundant array.
  6. Java&amp;apos;s streams API makes an interesting distinction between (old) outer loops and the internal streams of streams. LINQ and streams put it to extremes: there needs not even to be a solid collection to do operations on it!