Create List of Object From Another Type Using Java 8

1. Overview

When we work with Java, sometimes we want to generate a list from another list of objects. Java 8 introduced a set of new features that streamline such operations.

So, in this tutorial, we’ll explore how to create a list of objects of a different type based on a given list, using the powerful features introduced in Java 8 and beyond.

2. Introduction to the Problem

As usual, let’s understand the problem through examples.

Let’s say a company is looking to kickstart an internal tennis tournament. Now, the tournament committee wants a player candidate list from all company employees. So, we’ll take this task and create a program to build up the player candidate list.

The Employee class is ready:

@Getter
class Employee {
    private final String name;
    private final Set<String> hobbies = new HashSet<>();
    private final String email;
    private String department;
    // ... other attributes
    public Employee(String name, String email, Collection<String> hobbies) {
        this.name = name;
        this.email = email;
        this.hobbies.addAll(hobbies);
    }
}

As the code above shows, we use Lombok‘s @Getter annotation to make the Employee class have getter methods for all properties.

Each Employee object carries the hobbies Set, which holds the employee’s hobbies in String. Our task involves walking through the employees. If an employee lists “Tennis” as one of their hobbies, we consider them a potential candidate to participate as a tennis player in the tournament. Thus, in the end, we’ll have a list of TennisPlayerCandidate instances:

class TennisPlayerCandidate {
    private final String name;
    private final String email;
    private final Boolean confirmed = Boolean.FALSE;
    public TennisPlayerCandidate(String name, String email) {
        this.name = name;
        this.email = email;
    }
    
  // equals() and hashcode() methods are omitted
}

As our input, let’s assume the EMPLOYEES list contains five objects:

final static List<Employee> EMPLOYEES = Lists.newArrayList(
  new Employee("Kai", "kai@company.com", Lists.newArrayList("Football", "Reading", "Chess")),
  new Employee("Eric", "eric@company.com", Lists.newArrayList("Tennis", "Baseball", "Singing")),
  new Employee("Saajan", "saajan@company.com", Lists.newArrayList("Tennis", "Baseball", "Reading")),
  new Employee("Kevin", "kevin@company.com", Lists.newArrayList("Dancing", "Computer Games", "Tennis")),
  new Employee("Amanda", "amanda@company.com", Lists.newArrayList("Painting", "Yoga", "Dancing"))
);

Based on this input, we aim to get this list of TennisPlayerCandidate instances:

final static List<TennisPlayerCandidate> EXPECTED = Lists.newArrayList(
  new TennisPlayerCandidate("Eric", "eric@company.com"),
  new TennisPlayerCandidate("Saajan", "saajan@company.com"),
  new TennisPlayerCandidate("Kevin", "kevin@company.com")
);

Next, let’s see different solutions to build up the expected List<TennisPlayerCandidate> from the given List<Employee>.

For simplicity, we’ll use unit test assertions to verify whether each approach can produce the expected result.

3. Using the List.forEach() Method

One straightforward approach to solve this problem is to start by initializing an empty candidate list. Then, we traverse the EMPLOYEES list, creating a TennisPlayerCandidate object for each employee who lists tennis as a hobby. We add employees to the candidate list if they meet this criterion.

Java 8 introduced the forEach() method, which allows us to perform actions while traversing through a list conveniently:

List<TennisPlayerCandidate> result = new ArrayList<>();
EMPLOYEES.forEach(e -> {
    if (e.getHobbies().contains("Tennis")) {
        result.add(new TennisPlayerCandidate(e.getName(), e.getEmail()));
    }
});
assertEquals(EXPECTED, result);

As we can see, this approach does the job effectively.

Apart from the forEach() method, since Java 8, the Stream API has revolutionized how we manipulate and transform data collections.

Next, let’s use the Stream API to solve the problem.

4. Using Stream.map() or Collectors.mapping()

We can interpret the problem in this way: filtering the employees whose hobbies cover tennis and transforming these Employee objects into TennisPlayerCandidate objects.

Stream’s filter() and map() methods can support us to finish the task easily. Next, let’s “translate” the idea into Java code:

List<TennisPlayerCandidate> result = EMPLOYEES.stream()
  .filter(e -> e.getHobbies().contains("Tennis"))
  .map(e -> new TennisPlayerCandidate(e.getName(), e.getEmail()))
  .collect(Collectors.toList());
assertEquals(EXPECTED, result);

As the code above shows, preparing an empty list for TennisPlayerCandidate objects is unnecessary. The filter().map() pipeline delivers a Stream of TennisPlayerCandidate instances. What we need to do is just collect the objects into a list.

Alternatively, we can move the mapping logic to the collecting phase. In other words, we transform the filtered Employee instances to TennisPlayerCandidate when we collect them. 

The Collectors.mapping() method allows us to perform object transformation and collection from a Stream:

List<TennisPlayerCandidate> result = EMPLOYEES.stream()
  .filter(e -> e.getHobbies().contains("Tennis"))
  .collect(Collectors.mapping(e -> new TennisPlayerCandidate(e.getName(), e.getEmail()), Collectors.toList()));
assertEquals(EXPECTED, result);

5. Conclusion

In this article, we’ve explored three approaches to creating a list of objects of a different type based on a given list. Through the examples, we learned that the Stream API enhances the productivity and readability of code when working with lists in Java.

As always, the complete source code for the examples is available over on GitHub.

       


电子产品 排行榜


Gurmandise 哆啦A梦 铜锣烧 手机手环

IT電腦補習 java補習 為大家配對電腦補習,IT freelance, 私人老師, PHP補習,CSS補習,XML,Java補習,MySQL補習,graphic design補習,中小學ICT補習,一對一私人補習和Freelance自由工作配對。
立刻註冊及報名電腦補習課程吧!

facebook 查詢:
24 hours enquiry facebook channel :
https://www.facebook.com/itteacheritfreelance/?ref=aymt_homepage_panel

Be the first to comment

Leave a Reply

Your email address will not be published.


*