1. 程式人生 > >Java8新特性之Stream詳解二

Java8新特性之Stream詳解二

       最近在公司的專案中常用Stream結合Lambda表示式來操作集合,使得專案整體程式碼簡潔和整齊;並且上一章也講了一些關於Stream的常用操作,比如:map()、filter()、concat()、reduce()、max()、min()、distinct()等常用操作。這篇我就分享一下Stream中List、Set、Map之間的轉換操作:

準備工作:新建一個Course類,包含name、credit兩個屬性,並重寫hashCode()、equals()方法:

class Course {
    private String name;

    private Integer credit;

    public Course(String name, Integer credit) {
        this.name = name;
        this.credit = credit;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getCredit() {
        return credit;
    }

    public void setCredit(Integer credit) {
        this.credit = credit;
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        Course stu = null;
        if (obj != null && obj instanceof Course) {
            stu = (Course) obj;
            if (this.name.equals(stu.getName()) && this.credit.equals(stu.getCredit())) {
                return true;
            }
        }
        return false;
    }
}

一、Stream將List轉換為Map集合

/**
 * Stream將List轉換為Map集合
 */
@Test
public void listToMap() {
    List<Course> stuList = Arrays.asList(
        new Course("Android", 10),
        new Course("Java", 8),
        new Course("Structure", 13),
        new Course("IOS", 12),
        new Course("Guava", 16),
        new Course("OS", 6));

    Map<String, Integer> nameAgeMap = stuList.stream().
        collect(Collectors.toMap(Course::getName, Course::getCredit));
    nameAgeMap.entrySet().stream().forEach(x -> System.out.println(x.getKey() + ", " + x.getValue()));

    //Function.identity()指代本身,相當於 x -> x
    Map<String, Course> nameStuMap = stuList.stream().
        collect(Collectors.toMap(Course::getName, Function.identity()));
    nameStuMap.entrySet().stream().forEach(x -> System.out.println(x.getKey() + "," + x.getValue().getCredit()));
}

執行結果展示:(兩次結果展示一致)

Guava, 16
Java, 8
OS, 6
IOS, 12
Structure, 13
Android, 10

注意:collect(Collectors.toMap(Course::getName,Function.identity())) 得到的是<name,course>Map集合。

檢視Function.identity()底層實現原理:t -> t 返回物件本身

static <T> Function<T, T> identity() {
    return t -> t;
}

二、Stream將List轉換為Set集合

    @Test
    public void listToSet() {
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5);
        Set<Integer> integerSet = integerList.stream().
                collect(Collectors.toSet());
        integerSet.stream().forEach(System.out::print);
        System.out.println("");

        List<Course> courseList = Arrays.asList(
                new Course("Android", 10),
                new Course("Java", 8),
                new Course("Android", 10),
                new Course("IOS", 12),
                new Course("Guava", 16),
                new Course("Android", 6));
        //排序並去重
        List<Course> courList = courseList.stream().
                sorted(Comparator.comparing(Course::getName)).
                distinct().
                collect(Collectors.toList());
        courList.stream().forEach(c -> System.out.println(c.getName() + "," + c.getCredit()));

        //只去重Set
        Set<Course> courSet = courseList.stream().
                sorted(Comparator.comparing(Course::getName)).
                collect(Collectors.toSet());
        courSet.stream().forEach(c -> System.out.println(c.getName() + "," + c.getCredit()));
    }

結果展示:

12345
Android,10
Android,6
Guava,16
IOS,12
Java,8
Guava,16
Java,8
IOS,12
Android,10
Android,6

注意:物件去重需要重寫類的hashCode()、equals()方法,給出去重排序、去重的List轉換為Set集合。

Stream操作集合的功能十分強大,結合Lambda表示式使得程式碼簡潔大方、便捷,還有很多StreamAPI需要討論,後續待學希望一起討論進步......