Stream相關API學習使用記錄--(一)

1、前言

在之前的工做中,業務中不少時候是須要循環來獲取某一個列表中的一些數據,好比獲取某一個值作業務邏輯的判斷,或者獲取其中一部分的數據,如使用狀態的標誌位等等,這個時候可能不少時候都是使用簡單的for循環、Foreach循環或者迭代器等方式,不少時候爲了處理業務都是須要循環嵌套循環的。可是在Java8中爲集合的相關處理提供了一個更強大的工具,那麼就是Stream,在瀏覽代碼的時候看見了其餘人的書寫,感受很驚奇(此時本身也很無語,Java8出來這麼久了,本身好像好沒有意識到它到底添加了那些新的內容,有什麼新的特性,簡化了那些操做等等),因此本身就對這個東西充滿了好奇。數組

2、 Stream的基礎簡介

2.一、stream是什麼

它是Java8 API添加的一個新的抽象流,它把要處理的元素看作一種流,流在管道中傳輸,而且能夠在管道的節點上進行處理,例如排序,篩選和聚合等操做,可讓人以一種聲明的方式來處理數據。
元素流在管道中通過中間操做(intermediate operation)處理,最後由最終操做(terminal operation)獲得前面的處理結果。ide


+------------------------+                +---------+         +-----------+         +--------+        +-------+
| stream of elements +-------->   |filter    +-----> |sorted    +-----> |map    +----> |collect|
+-----------------------+                 +---------+         +-----------+          +--------+      +-------+工具

2.二、特性

stream是一個來自數據源的元素隊列並支持聚合操做:
(1)元素是特定的元素,造成一個隊列,可是stream不會存儲元素,而是按需計算
(2)數據源能夠是集合、數組、I/Ochannel等
(3)集合操做相似鏈式的SQL,如filter、map、reduce、find、match、sortde等this

2.三、流生成方式

2.3.一、串行流

使用stream方式,爲集合建立串行流spa

2.3.二、並行流

使用parallelStream 爲集合建立並行流code

3、管道節點

3.一、ForEach

Stream提供了新的方法來迭代流中的每個數據blog

public class StreamDemoTest {

    private final static Integer MAX_CIRCLE = 100;
    public static void main(String[] args) {
        List<Integer> strList = new ArrayList<>();
        Map<Integer, String> integerMap = new HashMap<>();
        for (int i = 0; i < MAX_CIRCLE; i++) {
            strList.add(i);
            integerMap.put(i, i+"e");
        }
         strList.stream().forEach(s -> System.out.println(s));
    }
}

3.二、map

map方法用於映射每一個元素到對應的結果排序

public class StreamDemoTest {

    private final static Integer MAX_CIRCLE = 100;
    public static void main(String[] args) {
        List<Integer> strList = new ArrayList<>();
        Map<Integer, String> integerMap = new HashMap<>();
        for (int i = 0; i < MAX_CIRCLE; i++) {
            strList.add(i);
            integerMap.put(i, i+"e");
        }
         //strList.stream().forEach(s -> System.out.println(s));
        List<Integer> integerList = strList.stream().map(i -> i * i).collect(Collectors.toList());
        integerList.stream().forEach(s -> System.out.println(s));

    }
}

3.三、filter

filter用於經過設置的條件過濾出元素繼承

List<String> stringList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        // 獲取空字符串的數量
        long count = stringList.stream().filter(string ->string!="abc").count();
    //獲取不是abc和空的字符串
        List<String> list = stringList.stream().filter(str -> str != "abc"&&str!="").collect(Collectors.toList());

3.四、limit

用於獲取指定數量的流隊列

List<String> stringList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        // 獲取空字符串的數量
        long count = stringList.stream().filter(string ->string!="abc").count();
        //限定獲取過濾條件後的數量
        List<String> list = stringList.stream().filter(str -> str != "abc"&&str!="").limit(3).collect(Collectors.toList());
        list.stream().forEach(s-> System.out.println(s));

limit的位置能夠在filter前面或者後面,只是表示的含義不同而已。

3.四、sorted

sorted用於對流進行排序

 
public static void main(String[] args) {
        List<String> strList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        //天然排序
        System.out.println("天然排序");
        strList.stream().sorted().forEach(s -> System.out.println(s));

        System.out.println("倒序排序");
        strList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));
    }

輸出結果已經按照要求進行了排序,默認的是升序排列了,若是想簡單的倒序排序,可使用 Stream<T> sorted(Comparator<? super T> comparator)方法,裏面採用Comparator.reverseOrder()進行倒序排序。
若是是自定義的其餘的類型,怎麼進行排序那?

下面是自定義的一個用戶信息的簡單實體

class User {
    /**
     * 姓名
     **/
    private String userName;
    /**
     * 英文名稱
     **/
    private String englishName;
    /**
     * 年齡
     **/
    private int age;
    /**
     * 住址
     **/
    private String address;
    /**
     * 電話
     **/
    private String tel;

    public User(String userName, String englishName, int age) {
        this.userName = userName;
        this.englishName = englishName;
        this.age = age;
    }

    public User(String userName, String englishName, int age, String address, String tel) {
        this.userName = userName;
        this.englishName = englishName;
        this.age = age;
        this.address = address;
        this.tel = tel;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getEnglishName() {
        return englishName;
    }

    public void setEnglishName(String englishName) {
        this.englishName = englishName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

@Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", englishName='" + englishName + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", tel='" + tel + '\'' +
                '}';
    }
}
public static void main(String[] args) {
       /* List<String> strList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        //天然排序
        System.out.println("天然排序");
        strList.stream().sorted().forEach(s -> System.out.println(s));

        System.out.println("倒序排序");
        strList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));*/

        List<User> userList = new ArrayList<>();
        User user = new User("Angle", "B", 10);
        userList.add(user);
        user = new User("Heni", "G", 39);
        userList.add(user);
        user = new User("Eson", "F", 6);
        userList.add(user);
        user = new User("Cily", "D", 2);
        userList.add(user);
        user = new User("Cily", "G", 6);
        userList.add(user);
        user = new User("Eson", "G", 6);
        userList.add(user);
        System.out.println("正常輸出");
        userList.stream().forEach(s-> System.out.println(s.toString()));


        System.out.println("按照名稱默認升序排列");
        userList.stream().sorted(Comparator.comparing(User::getUserName)).forEach(s -> System.out.println(s));

        System.out.println("按照名稱進行倒序排列");
        userList.stream().sorted(Comparator.comparing(User::getUserName).reversed()).forEach(s -> System.out.println(s));

        System.out.println("多元素排列");
        userList.stream().sorted(Comparator.comparing(User::getUserName).thenComparing(User::getAge).reversed()).forEach(s -> System.out.println(s));

        System.out.println("轉換爲map");
        userList.stream().collect(Collectors.toMap(User::getUserName,User::getAge,(newValue,oldValue)->newValue)).entrySet().stream().forEach(e-> {
            System.out.println(e.getKey()+"====="+e.getValue());
        });

        System.out.println("過濾之後的");
        userList.stream().filter(e -> e.getUserName().equals("Eson")).sorted(Comparator.comparing(User::getAge).reversed())
                .forEach(e -> System.out.println(e.getUserName() + "======" + e.getAge()));

        System.out.println("若是是重複的key,值轉爲list");
        Map<String, List<String>> map = userList.stream().collect(Collectors.toMap(User::getUserName,p->{
            List<String> ageList = new ArrayList<>();
            ageList.add(p.getAge() + "");
            return ageList;
        },(List<String> valueNew,List<String> valueOld)->{
            valueNew.addAll(valueOld);
            return valueNew;
        }));
        map.entrySet().stream().forEach(e-> {
            System.out.println(e.getKey()+"====="+e.getValue());
        });
    }

 

輸出結果:

正常輸出
User{userName='Angle', englishName='B', age=10, address='null', tel='null'}
User{userName='Heni', englishName='G', age=39, address='null', tel='null'}
User{userName='Eson', englishName='F', age=6, address='null', tel='null'}
User{userName='Cily', englishName='D', age=2, address='null', tel='null'}
User{userName='Cily', englishName='G', age=6, address='null', tel='null'}
按照名稱默認升序排列
User{userName='Angle', englishName='B', age=10, address='null', tel='null'}
User{userName='Cily', englishName='D', age=2, address='null', tel='null'}
User{userName='Cily', englishName='G', age=6, address='null', tel='null'}
User{userName='Eson', englishName='F', age=6, address='null', tel='null'}
User{userName='Heni', englishName='G', age=39, address='null', tel='null'}
按照名稱進行倒序排列
User{userName='Heni', englishName='G', age=39, address='null', tel='null'}
User{userName='Eson', englishName='F', age=6, address='null', tel='null'}
User{userName='Cily', englishName='D', age=2, address='null', tel='null'}
User{userName='Cily', englishName='G', age=6, address='null', tel='null'}
User{userName='Angle', englishName='B', age=10, address='null', tel='null'}
多元素排列
User{userName='Heni', englishName='G', age=39, address='null', tel='null'}
User{userName='Eson', englishName='F', age=6, address='null', tel='null'}
User{userName='Cily', englishName='G', age=6, address='null', tel='null'}
User{userName='Cily', englishName='D', age=2, address='null', tel='null'}
User{userName='Angle', englishName='B', age=10, address='null', tel='null'}

能夠看出來,整個排序是至關的簡單了,不須要本身的類繼承comparable,也不須要本身擴展排序comparator了。
對於map類型格式的數據。能夠對鍵排序或者值排序

 1 public static void main(String[] args) {
 2         Map<String, String> map = new LinkedHashMap<String, String>();
 3         map.put("12", "ddd");
 4         map.put("23", "eee");
 5         map.put("34", "ddw");
 6         map.put("21", "ecc");
 7 
 8         System.out.println("根據值排序");
 9         map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).forEach(e -> {
10             String key = e.getKey();
11             String value = e.getValue();
12             System.out.println("鍵值"+key+"值"+value);
13         });
14         System.out.println("根據鍵排序");
15         map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(e -> {
16             //System.out.println(e.toString());
17             String key = e.getKey();
18             String value = e.getValue();
19             System.out.println("鍵值"+key+"值"+value);
20         });
21 }

輸出的結果:

根據值排序
鍵值12值ddd
鍵值34值ddw
鍵值21值ecc
鍵值23值eee
根據鍵排序
鍵值12值ddd
鍵值21值ecc
鍵值23值eee
鍵值34值ddw

綜合看下來,使用對應的Stream比使用日常簡單的循環而言代碼量少了不少。

相關文章
相關標籤/搜索