1. Introduction

In this tutorial, we’re going to show how to inject Java collections using the Spring framework.

Simply put, we’ll demonstrate examples with the List, Map, Set collection interfaces.

2. List With @Autowired

Let’s create an example bean:

public class CollectionsBean {

    @Autowired
    private List<String> nameList;

    public void printNameList() {
        System.out.println(nameList);
    }
}

Here, we declared the nameList property to hold a List of String values.

In this example, we use field injection for nameList. Therefore, we put the @Autowired annotation.

To learn more about the dependency injection or different ways to implement it, check out this guide.

After, we register the CollectionsBean in the configuration setup class:

@Configuration
public class CollectionConfig {

    @Bean
    public CollectionsBean getCollectionsBean() {
        return new CollectionsBean();
    }

    @Bean
    public List<String> nameList() {
        return Arrays.asList("John", "Adam", "Harry");
    }
}

Besides registering the CollectionsBean, we also inject a new list by explicitly initializing and returning it as a separate @Bean configuration.

Now, we can test the results:

ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class);
CollectionsBean collectionsBean = context.getBean(
  CollectionsBean.class);
collectionsBean.printNameList();

The output of printNameList() method:

[John, Adam, Harry]

3. Set With Constructor Injection

To set up the same example with the Set collection, let’s modify the CollectionsBean class:

public class CollectionsBean {

    private Set<String> nameSet;

    public CollectionsBean(Set<String> strings) {
        this.nameSet = strings;
    }

    public void printNameSet() {
        System.out.println(nameSet);
    }
}

This time we want to use a constructor injection for initializing the nameSet property. This requires also changes in configuration class:

@Bean
public CollectionsBean getCollectionsBean() {
    return new CollectionsBean(new HashSet<>(Arrays.asList("John", "Adam", "Harry")));
}

4. Map With Setter Injection

Following the same logic, let’s add the nameMap field to demonstrate the map injection:

public class CollectionsBean {

    private Map<Integer, String> nameMap;

    @Autowired
    public void setNameMap(Map<Integer, String> nameMap) {
        this.nameMap = nameMap;
    }

    public void printNameMap() {
        System.out.println(nameMap);
    }
}

This time we have a setter method in order to use a setter dependency injection. We also need to add the Map initializing code in configuration class:

@Bean
public Map<Integer, String> nameMap(){
    Map<Integer, String>  nameMap = new HashMap<>();
    nameMap.put(1, "John");
    nameMap.put(2, "Adam");
    nameMap.put(3, "Harry");
    return nameMap;
}

The results after invoking the printNameMap() method:

{1=John, 2=Adam, 3=Harry}

5. Injecting Bean References

Let’s look at an example where we inject bean references as elements of the collection.

First, let’s create the bean:

public class BaeldungBean {

    private String name;

    // constructor
}

And add a List of BaeldungBean as a property to the CollectionsBean class:

public class CollectionsBean {

    @Autowired(required = false)
    private List<BaeldungBean> beanList;

    public void printBeanList() {
        System.out.println(beanList);
    }
}

Next, we add the Java configuration factory methods for each BaeldungBean element:

@Configuration
public class CollectionConfig {

    @Bean
    public BaeldungBean getElement() {
        return new BaeldungBean("John");
    }

    @Bean
    public BaeldungBean getAnotherElement() {
        return new BaeldungBean("Adam");
    }

    @Bean
    public BaeldungBean getOneMoreElement() {
        return new BaeldungBean("Harry");
    }

    // other factory methods
}

The Spring container injects the individual beans of the BaeldungBean type into one collection.

To test this, we invoke the collectionsBean.printBeanList() method. The output shows the bean names as list elements:

[John, Harry, Adam]

Now, let’s consider a scenario when there is not a BaeldungBean. If there isn’t a BaeldungBean registered in the application context, Spring will throw an exception because the required dependency is missing.

We can use @Autowired(required = false) to mark the dependency as optional. Instead of throwing an exception, the beanList won’t be initialized and its value will stay null.

If we need an empty list instead of null, we can initialize beanList with a new ArrayList:

@Autowired(required = false)
private List<BaeldungBean> beanList = new ArrayList<>();

5.1. Using @Order to Sort Beans

We can specify the order of the beans while injecting into the collection.

For that purpose, we use the @Order annotation and specify the index:

@Configuration
public class CollectionConfig {

    @Bean
    @Order(2)
    public BaeldungBean getElement() {
        return new BaeldungBean("John");
    }

    @Bean
    @Order(3)
    public BaeldungBean getAnotherElement() {
        return new BaeldungBean("Adam");
    }

    @Bean
    @Order(1)
    public BaeldungBean getOneMoreElement() {
        return new BaeldungBean("Harry");
    }
}

Spring container first will inject the bean with the name “Harry”, as it has the lowest order value.

It will then inject the “John”, and finally, the “Adam” bean:

[Harry, John, Adam]

Learn more about @Order in this guide.

5.2. Using @Qualifier to Select Beans

We can use the @Qualifier to select the beans to be injected into the specific collection that matches the @Qualifier name.

Here’s how we use it for the injection point:

@Autowired
@Qualifier("CollectionsBean")
private List<BaeldungBean> beanList;

Then, we mark with the same @Qualifier the beans that we want to inject into the List:

@Configuration
public class CollectionConfig {

    @Bean
    @Qualifier("CollectionsBean")
    public BaeldungBean getElement() {
        return new BaeldungBean("John");
    }

    @Bean
    public BaeldungBean getAnotherElement() {
        return new BaeldungBean("Adam");
    }

    @Bean
    public BaeldungBean getOneMoreElement() {
        return new BaeldungBean("Harry");
    }

    // other factory methods
}

In this example, we specify that the bean with the name “John” will be injected into the List named “CollectionsBean”. The results we test here:

ApplicationContext context = new AnnotationConfigApplicationContext(CollectionConfig.class);
CollectionsBean collectionsBean = context.getBean(CollectionsBean.class);
collectionsBean.printBeanList();

From the output, we see that our collection has only one element:

[John]

6. Setting an Empty List as a Default Value

We can set the default value for an injected List property as an empty list by using the Collections.emptyList() static method:

public class CollectionsBean {

    @Value("${names.list:}#{T(java.util.Collections).emptyList()}")
    private List<String> nameListWithDefaultValue;
    
    public void printNameListWithDefaults() {
        System.out.println(nameListWithDefaultValue);
    }
}

If we run this with the “names.list” key not initialized via properties file:

collectionsBean.printNameListWithDefaults();

We’ll get an empty list as output:

[ ]

7. Summary

With this guide, we learned how to inject different types of Java collections using the Spring framework.

We also examined injection with reference types and how to select or order them inside of the collection.

As usual, the complete code is available in the GitHub project.