lambda表达式是jdk8的特性.lambda表达式的准则是:可推断,可省略.

常规代码写一个多线程

public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("run ");
}
}).start();
}
}

lambda表达式写一个多线程

public class Main {
public static void main(String[] args) {
new Thread(() -> System.out.println("run")).start();
}
}

lambda表达式的使用限制是.只能用来代替一个接口的方法.

自定义一个带参数的接口方法

public interface Person {
public void show(String name);
}
public class Main {
public static void main(String[] args) {
personShow((String name) -> {
System.out.println(name);
}, "张三");
} public static void personShow(Person p, String name) {
p.show(name);
}
}

lambda表达式语法分为两部分, 左边为参数,->右边为方法体.方法参数可以不指定类型,方法体如果只有一句可以省略大括号,省略return关键字.因为类型推断的原因,原则是能省就剩.

关于lambda表达式jdk8产生了一个新的注解@FunctionalInterface被这个注解修饰的接口,只能有一个抽象方法.称之为函数式接口.属于一个标记性接口,但是他对接口本身又有抽象方法个数的限制

JDK8内置的4个常用函数式接口

Consumer<T>:消费型接口 void accpet(T t);

public class Test1 {
public static void main(String[] args) {
Test1 test1 = new Test1();
test1.happy(1000,(m)-> System.out.println("您当前消费"+m+"元"));
} public void happy(double money, Consumer<Double> con) {
con.accept(money);
}
}

Supplier<T>:供给型接口 T get();

public class Test1 {
public static void main(String[] args) {
Test1 test1 = new Test1();
List list = test1.getNumList(5, () -> {
return 1;
});
System.out.println(list.size());
} public List<Integer> getNumList(int num, Supplier<Integer> sup) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(sup.get());
}
return list;
}
}

Fucntion<T,R>:函数型接口 R apply(T t);

public class Test1 {
public static void main(String[] args) {
Test1 test1 = new Test1();
String hehe = test1.strHandler("hehe", (s) -> s.toUpperCase());
System.out.println(hehe);
} public String strHandler(String str, Function <String,String> f){
return f.apply(str);
}
}

Predicate<T>:断言型接口 boolean test(T t);

public class Test1 {
public static void main(String[] args) {
Test1 test1 = new Test1();
boolean b = test1.is(1, (s) -> s > 3);
System.out.println(b);
} public boolean is(int n, Predicate<Integer> p) {
return p.test(n);
}
}

像这类的函数式接口定义的原因只是为了在我们需要自定义函数式接口时,可以使用定义好的函数式接口.

Stream流

先把源数据(集合只能是Collection集合,数组)变成流,然后对流中的数据进行操作,然后产生一个新的流.不会改变源数据.

public class Employee {
private String name;
private Integer age;
private Double pay; public Employee(String name, Integer age, Double pay) {
this.name = name;
this.age = age;
this.pay = pay;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public Double getPay() {
return pay;
} public void setPay(Double pay) {
this.pay = pay;
} @Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", pay=" + pay +
'}';
} @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return Objects.equals(name, employee.name) &&
Objects.equals(age, employee.age) &&
Objects.equals(pay, employee.pay);
} @Override
public int hashCode() {
return Objects.hash(name, age, pay);
}
}
public class Test {
public static void main(String[] args) {
//集合获取流
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
Stream<String> stringStream = list.parallelStream(); //数组获取流,Stream IntStream LongStream 都继承自BaseStream
Stream<String> stream1 = Arrays.stream(new String[10]);
IntStream stream2 = Arrays.stream(new int[10]);
LongStream stream3 = Arrays.stream(new long[10]);
}
}

筛选与切片

filter--接收lambda,从流中排除某些元素

public class Test2 {
public static void main(String[] args) {
//创建源数据
List<Employee> employees = Arrays.asList(
new Employee("张十八", 18, 9999.99),
new Employee("张五十八", 58, 5555.55),
new Employee("张二十六", 26, 3333.33),
new Employee("张三十六", 36, 6666.66),
new Employee("张十二", 12, 8888.88)); //转换成流,对流中的数据进行过滤操作
Stream<Employee> employeeStream = employees.stream()
.filter((e) -> e.getAge() > 18); //终止操作
     //注意终止操作不可做两次,本身意义就像是,一个桶里装满了水,当我们终止操作相当于将水倒了出来,是不能进行重复操作的.
     employeeStream.forEach((x)-> System.out.println(x));
}
}
Employee{name='张五十八', age=58, pay=5555.55}
Employee{name='张二十六', age=26, pay=3333.33}
Employee{name='张三十六', age=36, pay=6666.66}

limit--截断流,使其元素不超过给定数量

public class Test2 {
public static void main(String[] args) {
//创建源数据
List<Employee> employees = Arrays.asList(
new Employee("张十八", 18, 9999.99),
new Employee("张五十八", 58, 5555.55),
new Employee("张二十六", 26, 3333.33),
new Employee("张三十六", 36, 6666.66),
new Employee("张十二", 12, 8888.88)); //转换成流,对流中的数据进行过滤操作
Stream<Employee> employeeStream = employees.stream()
.limit(2); //终止操作
employeeStream.forEach((x)-> System.out.println(x));
}
}
Employee{name='张十八', age=18, pay=9999.99}
Employee{name='张五十八', age=58, pay=5555.55}

skip(n)--跳过元素,返回一个扔掉了前n个元素的流,若流中的元素不足n个,则返回一个空流,与limit(n)互补

public class Test2 {
public static void main(String[] args) {
//创建源数据
List<Employee> employees = Arrays.asList(
new Employee("张十八", 18, 9999.99),
new Employee("张五十八", 58, 5555.55),
new Employee("张二十六", 26, 3333.33),
new Employee("张三十六", 36, 6666.66),
new Employee("张十二", 12, 8888.88)); //转换成流,对流中的数据进行过滤操作
Stream<Employee> employeeStream = employees.stream()
.skip(2); //终止操作
employeeStream.forEach((x)-> System.out.println(x));
}
}
Employee{name='张二十六', age=26, pay=3333.33}
Employee{name='张三十六', age=36, pay=6666.66}
Employee{name='张十二', age=12, pay=8888.88}

distinct--筛选,通过流所产生的hashCode()和equals()去除重复元素

public class Test2 {
public static void main(String[] args) {
//创建源数据
List<Employee> employees = Arrays.asList(
new Employee("张十八", 18, 9999.99),
new Employee("张十八", 18, 9999.99),
new Employee("张十八", 18, 9999.99),
new Employee("张五十八", 58, 5555.55),
new Employee("张二十六", 26, 3333.33),
new Employee("张三十六", 36, 6666.66),
new Employee("张十二", 12, 8888.88)); //转换成流,对流中的数据进行过滤操作
Stream<Employee> employeeStream = employees.stream()
.distinct(); //终止操作
employeeStream.forEach((x)-> System.out.println(x));
}
}
Employee{name='张十八', age=18, pay=9999.99}
Employee{name='张五十八', age=58, pay=5555.55}
Employee{name='张二十六', age=26, pay=3333.33}
Employee{name='张三十六', age=36, pay=6666.66}
Employee{name='张十二', age=12, pay=8888.88}

映射

map--接收lambda,对流中的每一个记录都进行操作,然后将操作的返回值,从新读取到一个新的流中,注意这个map是有返回值的.我之所以会写上return 和{} 就是为了显示map产生的新流只是返回值的结果集合

public class Test3 {
public static void main(String[] args) {
//创建源数据
List<Employee> employees = Arrays.asList(
new Employee("张十八", 18, 9999.99),
new Employee("张五十八", 58, 5555.55),
new Employee("张二十六", 26, 3333.33),
new Employee("张三十六", 36, 6666.66),
new Employee("张十二", 12, 8888.88)); employees.stream()
.map((e) -> {
return e.getPay().intValue();
})
.forEach((e) -> System.out.println(e));
}
}

flatMap--接收一个函数作为参数,将流中的每个值都转换成另一个流,然后把所有流都连接成一个流

public class Test3 {
public static void main(String[] args) {
List<String> arrayList = Arrays.asList("a", "b", "c", "d"); //当一个流的元素还是流
Stream<Stream<Character>> streamStream = arrayList.stream().map((e) -> filterCharacter(e));
//双重forEach
streamStream.forEach((e) -> {
e.forEach((i) -> System.out.println(i));
}); System.out.println("-----------------------------");
//使用flatMap可以将多个流直接转换成一个流
Stream<Character> characterStream = arrayList.stream().flatMap((e) -> filterCharacter(e));
characterStream.forEach((e) -> {
System.out.println(e);
}); } public static Stream<Character> filterCharacter(String str) {
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
}
a
b
c
d
-----------------------------
a
b
c
d

排序

sorted()自然排序

public class Test4 {
public static void main(String[] args) {
List<String> arrayList = Arrays.asList("b","a","c");
arrayList.stream()
.sorted()
.forEach((e)-> System.out.println(e));
}
}
a
b
c

sorted(Comparator com)定制排序

public class Test4 {
public static void main(String[] args) {
//创建源数据
List<Employee> employees = Arrays.asList(
new Employee("张十八", 18, 9999.99),
new Employee("张五十八", 58, 5555.55),
new Employee("张二十六", 26, 3333.33),
new Employee("张三十六", 36, 6666.66),
new Employee("张十二", 12, 8888.88));
employees.stream()
.sorted((e1, e2) -> {
return e1.getPay().compareTo(e2.getPay());
})
.forEach((e) -> System.out.println(e));
}
}
Employee{name='张二十六', age=26, pay=3333.33}
Employee{name='张五十八', age=58, pay=5555.55}
Employee{name='张三十六', age=36, pay=6666.66}
Employee{name='张十二', age=12, pay=8888.88}
Employee{name='张十八', age=18, pay=9999.99}

我们对stream流中的数据进行操作,最终都有一个停止操作.与其说是停止操作,不如说是你要这个流最终干什么.我们也看到了,不管我们做切割,筛选等操作,最终返回的还是一个stream流,所以我们将stream流最终

变成我们需要的数据就是终止操作,以上我们用的forEach就是停止操作,尽管他没有返回值

查找与匹配

allMatch--检查是否匹配所有元素

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
boolean b = list.stream()
.allMatch((e) -> e == 1);
System.out.println(b);//false
}
}

anyMatch--检查是否至少匹配一个元素

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
boolean b = list.stream()
.anyMatch((e) -> e == 1);
System.out.println(b);//true
}
}

noneMatch--检查是否没有匹配所有元素

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
boolean b = list.stream()
.noneMatch((e) -> e == 1);
System.out.println(b);//false
}
}

findFirst--返回当前流中的第一个元素

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
Optional<Integer> first = list.stream()
.findFirst();
    //注意,此时返回的是一个Optional,这个是JDK8为了避免null而封装的一个对象
System.out.println(first.get());//1
}
}

findAny--返回流中的任意元素

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
     //其实就是随机返回了一个,但是为了演示明显这里使用了串行流,也就是多线程.
Optional<Integer> first = list.parallelStream()
.findAny();
System.out.println(first.get());//
}
}

count--返回流中的总个数

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
long count = list.parallelStream()
.count();
System.out.println(count);//
}
}

max--返回流中的最大值

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
Optional<Integer> max = list.parallelStream()
.max((x, y) -> Integer.compare(x, y));
System.out.println(max.get());//
}
}

min--返回流中的最小值

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
Optional<Integer> max = list.parallelStream()
.min((x, y) -> Integer.compare(x, y));
System.out.println(max.get());//
}
}

收集元素,将流中的数据转换成集合

public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3,4,5,6);
List<Integer> collect = list.stream()
.limit(2)
.collect(Collectors.toList());
System.out.println(collect.size());
}
}
public class Test5 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3,4,5,6);
LinkedHashSet<Integer> collect = list.stream()
.limit(2)
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println(collect.size());
}
}

函数式接口与Stream流的更多相关文章

  1. 黑马函数式接口学习 Stream流 函数式接口 Lambda表达式 方法引用

  2. 常用函数式接口与Stream API简单讲解

    常用函数式接口与Stream API简单讲解 Stream简直不要太好使啊!!! 常用函数式接口 Supplier<T>,主要方法:T get(),这是一个生产者,可以提供一个T对象. C ...

  3. Atiti 重定向标准输出到字符串转接口adapter stream流体系 以及 重定向到字符串

    Atiti 重定向标准输出到字符串转接口adapter stream流体系 以及 重定向到字符串 原理::syso  向ByteArrayOutputStream这个流理想write字节..然后可以使 ...

  4. 8000字长文让你彻底了解 Java 8 的 Lambda、函数式接口、Stream 用法和原理

    我是风筝,公众号「古时的风筝」.一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...

  5. 第46天学习打卡(四大函数式接口 Stream流式计算 ForkJoin 异步回调 JMM Volatile)

    小结与扩展 池的最大的大小如何去设置! 了解:IO密集型,CPU密集型:(调优)  //1.CPU密集型 几核就是几个线程 可以保持效率最高 //2.IO密集型判断你的程序中十分耗IO的线程,只要大于 ...

  6. Java8新特性_lambda表达式和函数式接口最详细的介绍

    Lambda表达式 在说Lambda表达式之前我们了解一下函数式编程思想,在数学中,函数就是有输入量.输出量的一套计算方案,也就是“拿什么东西做什么事情”. 相对而言,面向对象过分强调“必须通过对象的 ...

  7. JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用

    jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default   Lambda表达式     L ...

  8. Java的lamda表达式/函数式接口/流式计算

    在我们看他人code的时候经常会看到,可能会经常看到lambda表达式,函数式接口,以及流式计算.在刚接触这些新功能时,也觉得真的有必要吗?但是现在写多了,发现这个功能确实能简化代码结构,提升编码效率 ...

  9. Java Stream 函数式接口外部实例的引用

    Java Function Interface 函数式接口: Stream.empty() .filter(Predicate) .map(Function) .forEach(Consumer); ...

随机推荐

  1. 解决root用户下都无权限操作的问题

    问题现象: 有时系统设置了一种文件,无法编辑其所有权​ sudo chown users:username {filename} 或者root用户下执行 chown users:username {f ...

  2. Java 实现 HtmlEmail 邮件发送功能

    引言 在平常的企业级应用开发过程中,可能会涉及到一些资讯通知需要传达,以及软件使用过程中有一些安全性的东西需要及早知道和了解,这时候在局域网之间就可以通过发送邮件的方式了.以下就是代码实现了: pac ...

  3. mysql中的ifnull()函数判断空值

    我们知道,在不同的数据库引擎中,内置函数的实现.命名都是存在差异的,如果经常切换使用这几个数据库引擎的话,很容易会将这些函数弄混淆. 比如说判断空值的函数,在Oracle中是NVL()函数.NVL2( ...

  4. Java电商项目-3.使用VSFTPD_Nginx完成商品新增

    目录 到Github获取源码请点击此处 一. 商品类目查询 二. FTP图片服务器的搭建 图片上传思路介绍 Linux中安装vsftpd 接着配置ftp服务, 让外网可以访问 Http服务器搭建 Ng ...

  5. Java电商项目-1.构建数据库,搭建项目环境

    目录 到Github获取源码请点击此处 一. 数据库还原 二. Mybatis逆向生成工具的使用 三. 搭建项目环境 四. 在linux虚拟机上部署zookeeper, 搭建Dubbo服务. linu ...

  6. git报错:failed to push some refs to 'git@github.com:JiangXiaoLiang1988/CustomerHandl

    一.错误信息 今天在使用git将代码上传到GitHub的时候报下面的错误: 以前上传代码的时候重来没有出现这种错误,在网上查找了半天终于找到原因了:github中的README.md文件不在本地代码目 ...

  7. MVC教程:MVC区域路由

    一.区域路由 为了管理网站中大量的文件,在ASP.NET MVC 2.0版本中引入了一个新概念:区域(Area). 有了区域以后,可以让我们的项目不至于太复杂而导致管理混乱.每个模块的页面都放入相应的 ...

  8. Wpf,Unity6

    <?xml version="1.0" encoding="utf-8"?><packages> <package id=&quo ...

  9. CAD画三维图怎么渲染?一分钟教你快速操作

    从事过CAD相关工作的都知道,CAD绘制的方式有二维平面图以及三维图形,三维图形,画三维图方式也是比较简单的.那当然三维图画完后一般还需要进行渲染操作,步骤也是比较简洁的.下面就来给大家操作一下CAD ...

  10. 通过JS屏蔽鼠标右键

    我也是第一次接触这个功能,只需一行代码即可搞定,直译过来就是“屏蔽上下文菜单”,特此记录一下吧. document.oncontextmenu = () => false;