Filtering and Projecting collections in SpEL

In my previous two posts under Spring SpEL, I explained how to do filtering and projections using SpEL but separately.

In this post I will show an example in which I will combine both filtering and projections technique in one SpEL.

I will first do filtering on the collection and then on the result of filtering, I will apply projection.

For our example I will use the below Pojo class

Employee

package spel.package15;

public class Employee {
    private int id;
    private String name;
    private int salary;

    public Employee(int id, String name, int salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    //Removed the getter and setter for brevity
}

Below is the main class

Main class

package spel.package15;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

@Configuration
@ComponentScan(basePackages = "spel.package15")
public class Example15 {
    @Value("#{employees.?[salary > 500].![name]}")
    private List<String> filteredEmployeeNames;

    @Bean("employees")
    public List<Employee> getEmployees() {
        List<Employee> list = new ArrayList<>(0);
        for(int i = 1; i <= 10; i++) {
            Employee employee = new Employee(i, "name" + i, (i * 100));
            list.add(employee);
        }

        return list;
    }

    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example15.class);
        Example15 example15 = applicationContext.getBean(Example15.class);
        for(String name : example15.filteredEmployeeNames) {
            System.out.println(name);
        }
    }
}

In the above code, I created “employees” bean, through “getEmployees” method. The bean is a list containing 10 employees.

At line 16, I created an SpEL, the result of this expression is assigned to “filteredEmployeeNames” list.

In the expression first I apply filter on the “employees” collection, which will filter out employees whose salary is lesser then 500 (refer to condition starting with “.?” and ending before “.!”).

This filtered collection is passed to projection condition (refer to condition starting with “.!”) which will only retrieve “name” field of the filtered employees.

The result of this expression is a collection which will only contain names of employees whose salary is greater than 500.

In this way we can apply filter and projection on a collection.

Below is the output

Output

name6
name7
name8
name9
name10

Leave a comment