Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Lambdas with Collections

Header Image

Ahoy there, mateys! Today we’re going to be talking about lambdas and how they can be used with collections in Java. If you’re not familiar with lambdas, don’t worry - we’ll start with a brief introduction.

Using Lambdas with Collections

Lambdas are a shorthand way of writing anonymous functions. They can be used in place of anonymous inner classes to make your code more concise and readable. When it comes to collections, lambdas are particularly useful for iterating over them and performing operations on their elements.

Let’s start with an example. Imagine we have a collection of pirate hats, each represented by a string. We want to print out all of the hats in the collection. Here’s how we could do it with a lambda:

List<String> pirateHats = Arrays.asList("Tricorn", "Bicorne", "Feathered");
pirateHats.forEach(hat -> System.out.println(hat));

In this example, we’re using the forEach method on the pirateHats list to iterate over each element. The lambda expression hat -> System.out.println(hat) is used to define what we want to do with each element. It simply prints out the hat to the console.

We could achieve the same result using an anonymous inner class, like this:

pirateHats.forEach(new Consumer<String>() {
    @Override
    public void accept(String hat) {
        System.out.println(hat);
    }
});

As you can see, the lambda expression is much more concise and easier to read.

Common Collection Operations

Now that we know how to use lambdas with collections, let’s take a look at some common operations we can perform on them. Here are a few examples:

Filtering

We can use lambdas to filter a collection based on some criteria. For example, let’s say we have a list of pirate ships, each represented by a Ship object with a name and crewSize property. We can use a lambda to filter out all the ships with a crew size less than 10:

List<Ship> pirateShips = getSomeShips();
List<Ship> smallCrewShips = pirateShips.stream()
    .filter(ship -> ship.getCrewSize() < 10)
    .collect(Collectors.toList());

In this example, we’re using the stream method on the pirateShips list to create a stream of Ship objects. We then use the filter method to create a new stream containing only the ships with a crew size less than 10. Finally, we use the collect method to convert the stream back into a list.

Mapping

We can also use lambdas to map a collection of one type to a collection of another type. For example, let’s say we have a list of pirate chests, each represented by a Chest object with a gold property. We can use a lambda to create a list of integers representing the gold in each chest:

List<Chest> pirateChests = getSomeChests();
List<Integer> goldAmounts = pirateChests.stream()
    .map(chest -> chest.getGold())
    .collect(Collectors.toList());

In this example, we’re using the map method to create a new stream of integers representing the gold in each chest. We then use the collect method to convert the stream into a list.

Reducing

We can also use lambdas to reduce a collection down to a single value. For example, let’s say we have a list of integers representing theplunder taken from various raids, and we want to calculate the total amount of plunder. We can use a lambda to add up all the integers in the list:

List<Integer> plunderList = Arrays.asList(10000, 5000, 3000, 2000);
int totalPlunder = plunderList.stream()
    .reduce(0, (sum, plunder) -> sum + plunder);

In this example, we’re using the reduce method to add up all the integers in the plunderList list. The 0 parameter represents the initial value of the sum, and the lambda expression (sum, plunder) -> sum + plunder is used to add each element of the list to the sum.

Sorting

We can also use lambdas to sort a collection based on some criteria. For example, let’s say we have a list of pirate swords, each represented by a Sword object with a name and length property. We can use a lambda to sort the list by length:

List<Sword> pirateSwords = getSomeSwords();
pirateSwords.sort((s1, s2) -> s1.getLength() - s2.getLength());

In this example, we’re using the sort method on the pirateSwords list to sort it by length. The lambda expression (s1, s2) -> s1.getLength() - s2.getLength() is used to compare two swords by their length.

Collection Pipelines

One of the most powerful features of lambdas and collections is the ability to chain operations together in what’s called a “pipeline”. This allows us to perform complex operations on a collection in a single line of code. Here’s an example:

List<String> pirateNames = getSomeNames();
List<String> shortNames = pirateNames.stream()
    .filter(name -> name.length() < 5)
    .map(name -> name.toUpperCase())
    .sorted()
    .collect(Collectors.toList());

In this example, we’re using a pipeline to create a new list of pirate names that are shorter than 5 characters, converted to uppercase, and sorted alphabetically. The stream method is used to create a stream of strings, and each method in the pipeline performs an operation on the stream. Finally, the collect method is used to convert the stream back into a list.

Conclusion

And there you have it, mateys! Using lambdas with collections in Java can make your code more concise, readable, and powerful. We’ve covered some common collection operations and shown you how to chain them together in a pipeline. So the next time you’re plundering the high seas of Java, remember to use lambdas to make your code shipshape!

total amount of gold in all of our pirate chests. We can use a lambda to add up all the gold amounts:

List<Chest> pirateChests = getSomeChests();
int totalGold = pirateChests.stream()
    .mapToInt(chest -> chest.getGold())
    .sum();

In this example, we’re using the mapToInt method to create a new stream of integers representing the gold in each chest. We then use the sum method to add up all the gold amounts in the stream and get the total.

Sorting

We can also use lambdas to sort a collection based on some criteria. For example, let’s say we have a list of pirate swords, each represented by a Sword object with a name and attackPower property. We can use a lambda to sort the swords by attack power:

List<Sword> pirateSwords = getSomeSwords();
pirateSwords.sort((sword1, sword2) -> sword2.getAttackPower() - sword1.getAttackPower());

In this example, we’re using the sort method on the pirateSwords list to sort the swords by attack power. The lambda expression (sword1, sword2) -> sword2.getAttackPower() - sword1.getAttackPower() is used to define the sorting criteria. It subtracts the attack power of sword1 from the attack power of sword2, which causes the swords to be sorted in descending order by attack power.

Collection Pipelines

When working with collections and lambdas, it’s common to use a series of operations together in what’s called a “pipeline”. A pipeline is a sequence of operations that are applied to a collection in order to transform or manipulate it in some way. Let’s look at an example:

List<Pirate> crew = getSomePirates();
double averageAge = crew.stream()
    .filter(pirate -> pirate.getRank() == Rank.CAPTAIN)
    .mapToInt(Pirate::getAge)
    .average()
    .orElse(0.0);

In this example, we’re using a pipeline to calculate the average age of all the captains in our pirate crew. Here’s how it works:

  1. We start with a list of pirates in the crew variable.
  2. We create a stream of Pirate objects using the stream method.
  3. We use the filter method to create a new stream containing only the pirates with a rank of CAPTAIN.
  4. We use the mapToInt method to create a new stream of integers representing the age of each captain.
  5. We use the average method to calculate the average age of all the captains in the stream.
  6. We use the orElse method to handle the case where there are no captains in the stream (in this case, we simply return a default value of 0.0).

By using a pipeline, we’re able to chain together a series of operations that work together to achieve our desired result.

That’s it for using lambdas with collections, me hearties! Keep practicing and experimenting with these concepts, and you’ll soon be a master of functional programming in Java. Until next time, happy coding!

Intermediate and Terminal Operations in Collection Pipelines

In a collection pipeline, each operation (such as filter, map, sort, etc.) is either an intermediate operation or a terminal operation.

Intermediate operations are operations that produce a new stream, but don’t produce a final result. They’re typically used to transform or filter the elements in a stream. Examples of intermediate operations include filter, map, flatMap, and sorted.

Terminal operations, on the other hand, produce a final result from a stream. They’re typically used to aggregate, reduce, or collect the elements in a stream. Examples of terminal operations include count, average, min, max, reduce, and collect.

Combining Stream Operations with Lambdas

By combining intermediate and terminal operations in a collection pipeline, we can perform complex operations on our collections with just a few lines of code. Here’s an example that demonstrates how to use lambdas to find the oldest pirate in a collection:

List<Pirate> crew = getSomePirates();
Optional<Pirate> oldestPirate = crew.stream()
    .sorted((pirate1, pirate2) -> pirate2.getAge() - pirate1.getAge())
    .findFirst();

In this example, we’re using the stream method to create a stream of Pirate objects from the crew list. We then use the sorted method to sort the pirates by age, with the oldest pirate appearing first in the stream. Finally, we use the findFirst method to get the first pirate in the stream (which will be the oldest pirate, due to the sorting).

And there you have it, me hearties - a brief introduction to using lambdas with collections in Java. As you can see, lambdas are a powerful tool for functional programming in Java, and can help make your code more concise and readable. So keep practicing, and keep pushing the boundaries of what’s possible with lambdas and collections. Until next time, happy coding!