×

java8 stream list

java8的lambda表达式一些用法总结,以及流(stream)操作

我的笔记 我的笔记 发表于2019-08-15 10:05:00 浏览2789 评论0

抢沙发发表评论

首先我们拿一个例子来看一下lambda表达式长什么样子:

比如这段代码,是个循启动线程的代码

Runnable runnable=() -> System.out.println("启动线程");
new Thread(runnable).run();

可以看到有三部分组成

第一部分()小括号:这一部分是参数,如果有多个要用逗号隔开,和平时方法参数一样

第二部分 -> :这一个符号(->) 目前感觉没啥意义,就代表往下执行?

第三部分 System.out.println("启动线程"):这一部分就是个输出语句

要明白这三部分,首先明白Runnable中的方法的运行规则,所以我们来看一下Runnable的源码

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

我们可以看到,它就一个run方法,而且没有参数,所以我们小括号没有填东西,然后就是一个输出语句,这句话就是run方法的实现,当运行run方法的时候,就会运行打印语句。。

接下来我们一起看一下循环输出

public static void main(String[] args) {
   List<Persion> persions = new ArrayList<Persion>();
   Persion persion;
   for (int i = 0; i < 10; i++) {
      persion = new Persion(i + "", "张三" + i, "男" + i, "" + i);
      persions.add(persion);
   }

   persions.forEach((Persion p) -> System.out.println(p.getUserName()));
   
}

这一个向forEach方法传了一个Persion,然后在方法内调用了打印方法

此外我在项目中用到了list的stream操作,感觉很简便好用

比如我想求出List中所有对象的金额和,我就可以这样写

investorCaseList.stream().mapToDouble(InvestorCase::getSubscribedAmount).sum()

再比如我想求出List中Double和就是List<Double>形式的,没有属性,我可以这样写

fundCost.stream().reduce(Double::sum).orElse(0d)

总体来说,java8的新特性还是很好用的,

有同学可能看不懂Double::sumInvestorCase::getRealAmount,这两个的意思是方法调用,就是调用这个对象里的某个方法,相当于,Double.sum()InvestorCase。getRealAmount()


其次,我再说一下流(stream)方面的API,下面的我就直接转载别人的了

filter

在数据流中实现过滤功能是首先我们可以想到的最自然的操作了。Stream接口暴露了一个filter方法,它可以接受表示操作的Predicate实现来使用定义了过滤条件的lambda表达式。

import java.util.stream.Stream;

public class StreamDemo {
	public static void main(String[] args) {
		List<User> users = new ArrayList<User>();
		users.add(new User(20, "张三"));
		users.add(new User(22, "李四"));
		users.add(new User(10, "王五"));
		
		Stream<User> stream = users.stream();
		stream.filter(p -> p.getAge() > 20); //过滤年龄大于20的
	}
}

map

假使我们现在过滤了一些数据,比如转换对象的时候。Map操作允许我们执行一个Function的实现(Function<T,R>的泛型T,R分别表示执行输入和执行结果),它接受入参并返回。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
	public static void main(String[] args) {
		List<User> users = new ArrayList<User>();
		users.add(new User(20, "张三"));
		users.add(new User(22, "李四"));
		users.add(new User(10, "王五"));
		
		Stream<User> stream = users.stream();
		 //所有的年龄大于20岁的User对象,转换为字符串50对象。现在流中只有字符串对象了。
		stream.filter((User user) ->  user.getAge() > 20).map((User user) -> {return "50";});
	}
}

count

count方法是一个流的终点方法,可使流的结果最终统计,返回long

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Stream;

public class StreamDemo {
	public static void main(String[] args) {
		List<User> users = new ArrayList<User>();
		users.add(new User(20, "张三"));
		users.add(new User(22, "李四"));
		users.add(new User(10, "王五"));
		
		Stream<User> stream = users.stream();
		long count = stream.filter((User user) ->  user.getAge() >= 20).map((User user) -> {return "50";})
		.count(); //返回流中元素的个数。
		System.out.println(count);	
	}
}


我的笔记博客版权我的笔记博客版权