初探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>
為對象的流,而DoubleStream
、LongStream
以及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