Java Lambda表达式之从集合到流
从集合到流
现在我们用代码来具体表示对某一集合进行迭代操作,我们希望定义一个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
以上所述是小编给大家介绍的java lambda表达式之从集合到流,希望对大家有所帮助