java8 lambda、stream

java8的新特性☞ lambda表达式

lambda表达式可以简化内部类代码:

比如创建一个线程任务,以前的写法是

Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("成都in the house");
    }
});
t1.start();

用lambda表达式会简化代码:

Thread t1 = new Thread(()-> System.out.println("上海也in the house"));
t1.start();

 

lambda表达式的语法:

1.完全式语法

 

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
  statment1;
  statment2;
  //.............
  return statmentM;
}

2.单参数语法

param1 -> {
  statment1;
  statment2;
  //.............
  return statmentM;
}

举例:将集合中的字母都转换成大写

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5"});
List<String> list2 = list.stream().map(item -> {
    return item.toUpperCase();
}).collect(Collectors.toList());
System.out.println(list2);

3.单语句语法

当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号

List<String> collect = list.stream().map(bb -> bb.toUpperCase()).collect(Collectors.toList());
System.out.println(collect);

4.方法引用语法

List<String> collect = list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(collect);

 

这几种句法得出的结果都是一致的。

方法引用:

objectName::instanceMethod

ClassName::staticMethod

ClassName::instanceMethod

前两种方式类似,等同于把lambda表达式的参数直接当成instanceMethod|staticMethod的参数来调用。比如System.out::println等同于x->System.out.println(x);Math::max等同于(x, y)->Math.max(x,y)。

最后一种方式,等同于把lambda表达式的第一个参数当成instanceMethod的目标对象,其他剩余参数当成该方法的参数。比如String::toLowerCase等同于x->x.toLowerCase()。

可以这么理解,前两种是将传入对象当参数执行方法,后一种是调用传入对象的方法。

如何使用Stream?

对聚合操作的使用可以归结为3个部分:

  1. 创建Stream:通过stream()方法,取得集合对象的数据集。
  2. Intermediate:通过一系列中间(Intermediate)方法,对数据集进行过滤、检索等数据集的再次处理。如上例中,使用filter()方法来对数据集进行过滤。
  3. Terminal通过最终(terminal)方法完成对数据集中元素的处理。如上例中,使用forEach()完成对过滤后元素的打印。

在一次聚合操作中,可以有多个Intermediate,但是有且只有一个Terminal。也就是说,在对一个Stream可以进行多次转换操作,转换操作是lazy(惰性求值)的,只有在Terminal操作执行时,才会一次性执行。

Stream的操作分类

刚才提到的Stream的操作有Intermediate、Terminal和Short-circuiting:

  • Intermediate:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 skip、 parallel、 sequential、 unordered

  • Terminal:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、iterator

  • Short-circuiting:
    anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

惰性求值和及早求值方法

像filter这样只描述Stream,最终不产生新集合的方法叫作惰性求值方法;而像count这样最终会从Stream产生值的方法叫作及早求值方法。

如何判断一个操作是惰性求值还是及早求值,其实很简单,只需要看其返回值即可:如果返回值是Stream,那么就是惰性求值;如果返回值不是Stream或者是void,那么就是及早求值

在一个Stream操作中,可以有多次惰性求值,但有且仅有一次及早求值。

 

Stream语法

 

如何获取Stream?

1.Stream stream = Stream.of("a", "b", "c");

2.数组转换为一个流:

String [] strArray = new String[] {"a", "b", "c"};
    stream = Stream.of(strArray);

3.集合转换为一个流

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5","","aWm"});
Stream<String> stream = list.stream();

distinct去重

distinct: 对于Stream中包含的元素进行去重操作(去重逻辑依赖元素的equals方法)

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5","","aWm"});
long count = list.stream().distinct().count();
System.out.println(count);

输出结果4

 

filter过滤

filter: 对于Stream中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream只包含符合条件的元素;

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5","","aWm"});
long count = list.stream().filter(s->!s.isEmpty()).distinct().count();
System.out.println(count);

filter中的条件是不为空串的元素,并去重

输出结果3

 

map操作集合

map:可以遍历集合中的每个对象,并对其进行操作,map之后,用.collect(Collectors.toList())会得到操作后的集合。

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5","","aWm"});
List<String> collect = list.stream().map(s -> s + "===").collect(Collectors.toList());
System.out.println(collect);

拿到list的流,使用map操作,让每个元素拼接上“===”打印输出:[aWm===, ak47===, Mp5===, ===, aWm===]

如果操作需要多条语句,需要加上{},例如在实际开发中,去数据库查询2016,2017,2018年的销售额/购入额*100%

List<String> datas = Arrays.asList(new String[]{"2016", "2017", "2018"});
datas = years.parallelStream().map(s->{
    Double xse = industryDao.getSalesAmount(s.toString());
    Double gre = industryDao.getBuyAmount(s.toString());
    if (gre.equals(0.00))
        return 0.00;
    else
        return toDouble(Math.abs(xse) / Math.abs(gre) * 100);
    }
).collect(toList());

匹配(Match方法):

有的时候,我们只需要判断集合中是否全部满足条件,或者判断集合中是否有满足条件的元素,这时候就可以使用match方法:
allMatch:Stream 中全部元素符合传入的 predicate,返回 true
anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true

noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5","","aWm"});
boolean awm = list.stream().anyMatch(s -> s.equalsIgnoreCase("awm"));
System.out.println(awm);//true

 

reduce:汇聚

List<String> list = Arrays.asList(new String[]{"aWm","ak47","Mp5","","aWm"});
Optional<String> reduce = list.stream().reduce((a, b) -> a + b);
System.out.println(reduce);//Optional[aWmak47Mp5aWm]

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值