Java 8中Stream相關用法實踐

Java 8中Stream相關用法實踐

參考示例發下:

1. jcode-java-8-streams-collectors-flatmapping
2. java-8-collectors
3. java-8-collectors-groupingby-and-mapping-example
4. Collectors
5. java-8-convert-list-to-map
6. java8-Stream

Stream介紹

Stream 使用一種相似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。

Stream API能夠極大提升Java程序員的生產力,讓程序員寫出高效率、乾淨、簡潔的代碼。

這種風格將要處理的元素集合看做一種流,流在管道中傳輸,而且能夠在管道的節點上進行處理,好比篩選,排序,聚合等。

Stream有如下特性及優勢

1. 無存儲。Stream不是一種數據結構,它只是某種數據源的一個視圖,數據源能夠是一個數組,Java容器或I/O channel等。
2. 爲函數式編程而生。對Stream的任何修改都不會修改背後的數據源,好比對Stream執行過濾操做並不會刪除被過濾的元素,而是會產生一個不包含被過濾元素的新Stream。
3. 惰式執行。Stream上的操做並不會當即執行,只有等到用戶真正須要結果的時候纔會執行。
4. 可消費性。Stream只能被「消費」一次,一旦遍歷過就會失效,就像容器的迭代器那樣,想要再次遍歷必須從新生成.

示例以下

package net.liuzd.java.completable.future;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Test;

public class StreamTest {

    private static Random rand = new Random();

    void println(Object val) {
        System.out.println(val);
    }

    class Group {

        int    id;
        String name;

        @Override
        public String toString() {
            return "Group [id=" + id + ", name=" + name + "]";
        }

    }

    class User {

        int    id;
        int    age;
        int    groupId;
        String groupName;
        String name;
        int    money;

        @Override
        public String toString() {
            return "User [id=" + id + ", age=" + age + ", name=" + name + ", money=" + money + "]";
        }

        public int getId() {
            return id;
        }

        public int getGroupId() {
            return groupId;
        }

        public int getMoney() {
            return money;
        }

    }

    private List<User> getUserAll() {
        int size = rand.nextInt(100);
        Map<Integer, User> users = new HashMap<>();
        String[] names = new String[] { "趙", "孫", "李", "王", "劉" };
        for (int i = 0; i < size; i++) {
            User user = new User();
            user.id = rand.nextInt(size);
            user.age = rand.nextInt(150);
            user.groupId = rand.nextInt(5);// 用戶屬於5個組
            user.groupName = user.groupId + "- Name";
            user.name = rand.nextBoolean() ? names[rand.nextInt(names.length)] : null;
            user.money = rand.nextInt(1000);
            users.put(user.id, user);
        }
        return new ArrayList<>(users.values());
    }

    @Test
    public void testFilterNameEmpty() {
        //
        List<User> users = getUserAll();
        // 找出name爲空的用戶
        List<User> userNameEmptys = users.stream().filter(user -> user.name == null).collect(Collectors.toList());
        //
        println("名稱爲空的集合個數:" + userNameEmptys.size());
        userNameEmptys.stream().forEach(user -> {
            println("名稱爲空:" + user);
        });

    }

    @Test
    public void testFilterConditiom() {
        //
        List<User> users = getUserAll();
        // 更復雜的條件
        List<User> userNameEmptys = users.stream().filter(user -> {
            // 找出名稱爲空的用戶
            if (null != user.name) {
                return false;
            }
            // 找出名稱爲空的用戶而且年齡大於等於50的用戶
            if (user.age < 50) {
                return false;
            }
            // 找出名稱爲空的用戶而且年齡大於等於50,而且用戶金額小於30的用戶
            if (user.money >= 30) {
                return false;
            }
            // 符合條件的用戶
            return true;
        }).collect(Collectors.toList());
        //
        println("符合條件的用戶集合個數:" + userNameEmptys.size());
        userNameEmptys.stream().forEach(user -> {
            println("名稱爲空:" + user);
        });

    }

    @Test
    public void testMapOfUserToIds() {
        //
        List<User> users = getUserAll();
        // 找出用戶ID集合
        List<Integer> userIds = users.stream().filter(user -> user.id > 0).map(user -> user.id).collect(Collectors
                .toList());
        //
        println("用戶ID的集合個數:" + userIds.size());
        userIds.stream().forEach(id -> {
            println("ID:" + id);
        });

    }

    @Test
    public void testToMap() {
        //
        List<User> users = getUserAll();
        // 找出用戶ID集合
        Map<Integer, User> userMap = users.stream().filter(user -> user.id > 0).collect(Collectors.toMap(User::getId,
                Function.identity()));
        //
        println("用戶ID的集合個數:" + userMap.size());
        userMap.values().stream().forEach(user -> {
            println("User:" + user);
        });

    }

    @Test
    public void testToMapConvert() {
        //
        List<User> users = getUserAll();
        // 找出用戶ID集合
        List<Group> groups = users.stream().filter(user -> user.id > 0).map(user -> {
            Group g = new Group();
            g.id = user.groupId;
            g.name = user.groupName;
            return g;
        }).collect(Collectors.toList());
        //
        println("用戶ID所屬組集合個數:" + groups.size());
        groups.stream().forEach(group -> {
            println("Group:" + group);
        });

    }

    @Test
    public void testGroupingBy() {
        //
        // 找出組用戶集合
        Map<Integer, List<User>> groupUserMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
                .groupingBy(User::getGroupId));
        //
        println("用戶總共屬於組個數:" + groupUserMap.size());
        groupUserMap.values().stream().forEach(listUser -> {
            println("ListUser:" + listUser);
        });
        //
        Map<Integer, Long> groupCountsMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
                .groupingBy(User::getGroupId, Collectors.counting()));
        groupCountsMap.entrySet().stream().forEach(group -> {
            println("組ID:" + group.getKey() + ",個數:" + group.getValue());
        });
        //
        Map<Integer, Integer> groupUserMoneyMap = getUserAll().stream().filter(user -> user.id > 0).collect(Collectors
                .groupingBy(User::getGroupId, Collectors.summingInt(User::getMoney)));
        groupUserMoneyMap.entrySet().stream().forEach(group -> {
            println("組ID:" + group.getKey() + ",組用戶全部金額:" + group.getValue());
        });
        //
    }

    @Test
    public void testCollectingAndThen() {
        //
        List<User> users = getUserAll();
        println("用戶個數:" + users.size());
        users.addAll(getUserAll());
        println("添加後用戶個數:" + users.size());

        // 找出組用戶集合
        List<User> unique = users.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(User::getId))), ArrayList::new));
        //
        println("去除重複後用戶個數:" + unique.size());
        //

    }

    @Test
    public void testMapSum() {
        //
        Stream<String> s = Stream.of("1", "2", "3", "4", "4");
        //
        long ans = s.collect(Collectors.counting());
        println("個數:" + ans);
        //
        s = Stream.of("1", "2", "3", "4", "4");
        Set<String> set = s.collect(Collectors.toCollection(TreeSet::new));
        println("經Set後個數:" + set.stream().collect(Collectors.counting()));
        //
        s = Stream.of("1", "2", "3", "4", "4");
        String joined = s.map(Object::toString).collect(Collectors.joining(", "));
        println("joined : " + joined);
        // 用戶金額總和
        int sum = getUserAll().stream().mapToInt(User::getMoney).sum();
        println("用戶金額總和 : " + sum);
        //
        sum = getUserAll().stream().collect(Collectors.summingInt(User::getMoney));
        println("用戶金額總和 : " + sum);
        //
    }

}
相關文章
相關標籤/搜索