程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 初探Lambda表達式/Java多核編程【1】從集合到流

初探Lambda表達式/Java多核編程【1】從集合到流

編輯:關於JAVA

初探Lambda表達式/Java多核編程【1】從集合到流。本站提示廣大學習愛好者:(初探Lambda表達式/Java多核編程【1】從集合到流)文章只能為提供參考,不一定能成為您想要的結果。以下是初探Lambda表達式/Java多核編程【1】從集合到流正文


從集合到流

接上一大節初探Lambda表達式/Java多核編程【0】從內部迭代到外部迭代,本大節將著手運用“流”這一概念停止“迭代”操作。
首先何為“迭代”。其意為對某一對象停止某種操作,並把後果作為下一次操作的輸出,如此往復停止,直至失掉或迫近預期後果。
如今我們用代碼來詳細表示對某一集合停止迭代操作,我們希望定義一個Contact類來表示聯絡人,並將ContactList中一切String類型的聯絡人姓名全部包裝進Contact類中:

List<Contact> contacts = new ArrayList<>();
contactList.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        Contact contact = new Contact();
        contact.setName(s);
        contacts.add(contact);
    }
});

接上去我們希望挑選出一切還能打通的聯絡人,將其放入一個無效聯絡人集合:

List<Contact> validContacts = new ArrayList<>();
contacts.forEach(new Consumer<Contact>() {
    @Override
    public void accept(Contact c) {
        if (c.call())
            validContacts.add(c);
    }
});
System.out.println(validContacts.size());

可以看出,第一次操作我們將String類型的數據轉換為Contact,第二次則對每一個Contact調用call()辦法,挑選出前往後果為true的聯絡人並將其搜集進另一個集合,最後我們統計出還能打通的聯絡人數目。
在此進程中,操作行為完全封鎖在各個集合外部,無需引入任何內部變量。
從處置開端、停止到完畢,對象在操作間好像一個有序序列在挪動,這就是流的特征,即“挪動中的數據”。
真正的流與集合大相徑庭,其只表示一種“可選的有序值序列”,而“無需為這些值提供任何存儲”,這就是為何Stream在Java8-API中被定義為接口而非一品種。

public interface Stream<T> extends BaseStream<T, Stream<T>> {}

Stream<T>為對象的流,而DoubleStreamLongStream以及IntStream則為double、long以及int這三種根本類型的流。
如今我們再將第一次從String到Contact的映射用流的方式來重寫:

Stream<Contact> contactStream = contactList.stream().map(s -> new Contact().setName(s));

stream()從源中獲得管道,表示流的開端。
map()接納管道中的流並對其停止某種變換,在本例中,我們將管道中的String映射成為Contact類,自此,String管道成為Contact管道。
我們可以將上一段代碼拆分為:

Stream<String> stringStream = contactList.stream();
Stream<Contact> contactStream1 = stringStream.map(s -> new Contact().setName(s));

在根本搞清了流操作之後,我們如今一氣呵成,直接運用流失掉最終後果:

long validContactCounter = 
    contactList.stream()
        .map(s -> new Contact().setName(s))
        .filter(c -> c.call())
        .count();

可以看出,我們對流可以停止豐厚的操作,過濾、計數、查找等等,在此不表。

小結

運用流的方式處置數據可以精簡代碼,同時突出了所要停止的操作,當然乍看起來有些難懂。
既然犧牲了些答應讀性,但是作為交流條件,我們在這種順序執行的流操作中,取得了兩倍於相應的循環版本的功能。
異樣,並行執行流操作關於大型數據集將發生特殊的效果。

本大節相關代碼:
(Contact.java)

import java.util.Random;

public class Contact {
    private String name;
    private long number;
    private Random random;

    public Contact() {
        random = new Random();
    }

    public String getName() {
        return name;
    }

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

    public long getNumber() {
        return number;
    }

    public Contact setNumber(long number) {
        this.number = number;
        return this;
    }

    public boolean call() {
        return random.nextBoolean();
    }
}

(運轉用)

List<Contact> contacts = new ArrayList<>();
contactList.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        Contact contact = new Contact();
        contact.setName(s);
        contacts.add(contact);
    }
});
List<Contact> validContacts = new ArrayList<>();
contacts.forEach(new Consumer<Contact>() {
    @Override
    public void accept(Contact contact) {
        if (contact.call())
            validContacts.add(contact);
    }
});
System.out.println(validContacts.size());

//--- Stream is coming ---//
Stream<Contact> contactStream = contactList.stream().map(s -> new Contact().setName(s));

//--- Break this code ---//
Stream<String> stringStream = contactList.stream();
Stream<Contact> contactStream1 = stringStream.map(s -> new Contact().setName(s));
        
//--- All in one ---//
long validContactCounter = 
    contactList.stream()
        .map(s -> new Contact().setName(s))
        .filter(c -> c.call())
        .count();

System.out.println(validContactCounter);

以及運轉後果:

3
3



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved