2017-04-10 153 views
2

我想使用流創建類型B的類型集合。java 8創建類型A集合中的類型B的集合

假設我有兩個班

Class Employee{ 
    String firstName; 
    String lastName; 
    int age; 
    String id; 
    String email; 
    double salary; 
} 

Class Person { 
    String firstName; 
    String lastName; 
    String email; 
} 

從員工的集合創建人的集合,我寫下面的代碼

public static List<Person> createPersonsFromEmployees(List<Employee> employees) { 

     List<Person> persons = new ArrayList<>(); 

     employees.stream().filter(Object :: nonNull) 
        .forEach(e -> { 
         persons.add(new Person(e.getFirstName(), 
              e.getLastName(), 
              e.getEmail()); 
        };) 


     return persons; 
} 

目前,這段代碼工作。但我想知道並想知道是否有更好的方法來創建PersonEmployee而不使用forEach的集合。

回答

2

映射的EmployeePerson你可以使用別人已經提供Collectors.mapping/Stream.map所以我會跳過它。

注意到映射方式比地圖更快然後收集方式,因爲collect(mapping(...))是O(N),但map(...).collect(...)是O(2N),但map(...).collect(...)collect(mapping(...))的可讀性,並mapping指公用transform(Employee)方法引用,而不是Function<Employee,Person>這將被重新用作將Employee轉換爲Person的方法。然後兩個transform方法具有相同的語義,它們都是adapter方法。

public List<Person> transform(List<Employee> employees) throws Throwable { 
    return employees.stream() 
      .filter(Objects::nonNull) 
      .collect(Collectors.mapping(this::transform, Collectors.toList())); 
} 

public Person transform(Employee it) { 
    return new Person(it.firstName, it.lastName, it.email); 
} 
+0

感謝您的解釋。 – cmodha

3

創建適配器類:

class EmployeeToPersonAdapter { 

    private EmployeeToPersonAdapter() { 
    } 

    public static Person toPerson(Employee employee) { 
     if (employee == null) { 
      return null; 
     } 
     return new Person(employee.getFirstName(), 
       employee.getLastName(), 
       employee.getEmail()); 
    } 
} 

,然後使用它:

public static List<Person> createPersonsFromEmployees(List<Employee> employees) { 
    return employees.stream() 
      .filter(Objects::nonNull) 
      .map(EmployeeToPersonAdapter::toPerson) 
      .collect(Collectors.toList()); 
} 
+0

感謝你抽出你的時間,也分享的解決方案。 – cmodha

7

這裏做一個小更清潔的方式。在流中使用.forEach()表示可能有更好的方式來使用Stream。數據流意味着功能強大,他們儘量遠離可變性。

public static List<Person> createPersonsFromEmployees(List<Employee> employees) 
    Function<Employee, Person> employeeToPerson = e -> new Person(e.getFirstName, e.getLaseName(), e.getEmail()); 

    return employees.stream() 
        .filter(Object :: nonNull) 
        .map(employeeToPerson) 
        .collect(Collectors.toList()); 

} 
+1

我同意這個解決方案。我唯一要做的就是爲Person類創建一個Builder,以更智能的方式處理構造函數中的字段。 –

+0

非常感謝你分享你的想法和你的投入,以及如何讓它變得更好。 – cmodha