把运算过程封装成函数,通过函数调用的方式来实现相应的功能
// 过程式编程
Integer result=(a+b)*c-d;
// 函数式编程
Integer result = subtract(multiply(add(a,b), c), d);
接口中只包含一个抽象方法的接口叫函数式接口
java8 新增的函数式接口在java.util.funtion包下
常用的如下:
BiConsumer<T,U> // 接收两个参数没有返回值
BiFuction<T,U,R> // 两个参数,带返回值
Consumer<T> //接收一个参数无返回值
default: 接口中可以使用default关键字,让接口包含默认方法的实现,这样设计其实是为了兼容和扩展,一个接口被上万的类实现,如果接口中再增加一个抽象方法,上万个类都要修改,但是用default方法可以让这些类不需要修改.可以实现无缝增强功能.
一种让编写代码更快更优雅的特性
语法如下:
(arg1,arg2)->{ // 语句}
在用到函数式接口的地方都可以用lambda表达式,因为函数式接口只有一个抽象方法,方法的入参类型都可以确定下来,->后面跟着的就是对入参的操作了.
使用匿名内部类和lambda对比
@FunctionalInterface
public interface MyInterface {
void m1();
}
// 不使用labmda表达式,使用匿名内部类
MyInterface myInterface = new MyInterface() {
@Override
public void m1() {
System.out.println("no lambda");
}
};
myInterface.m1();
// use lambda
MyInterface myInterface1 = () -> System.out.println("lambda!");
myInterface1.m1();
带参数带返回值的
public interface MyInterfaceWithParam {
int sum(int a,int b);
}
MyInterfaceWithParam param = (a, b) -> a + b; // 省略return
System.out.println(param.sum(1, 2));
注: 函数式接口只有一个入参小括号可以省略,只有一条语句大括号可以省略; 带返回值的接口如果只有一条语句返回值可以省略;
便于对集合进行操作
public class Student {
private String name;
private Integer score;
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
public Student(String name, Integer score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
}
public class InitData {
public static List<Student> getList(){
List<Student> stuList = new ArrayList<>(10);
stuList.add(new Student("刘一", 85));
stuList.add(new Student("陈二", 90));
stuList.add(new Student("张三", 98));
stuList.add(new Student("李四", 88));
stuList.add(new Student("王五", 83));
stuList.add(new Student("赵六", 95));
stuList.add(new Student("孙七", 87));
stuList.add(new Student("周八", 84));
stuList.add(new Student("吴九", 100));
stuList.add(new Student("郑十", 95));
return stuList;
}
}
List<Student> list=InitData.getList();
public static void main(String[] args) {
List<Student> list=InitData.getList();
// 查找集合中大于等于90分的数据并降序排序
List<Student> result=new ArrayList<>(10);
for (Student s:stuList){
if (s.getScore()>=90){
result.add(s);
}
}
result.sort((s1,s2)->Integer.compare(s2.getScore(),s1.getScore()));
System.out.println(result);
// 使用stream实现
result=stuList.stream()
.filter(student -> student.getScore()>=90)
// .sorted((s1,s2)->Integer.compare(s2.getScore(),s1.getScore()))
.sorted(Comparator.comparing(Student::getScore).reversed())
.collect(Collectors.toList());
System.out.println(result);
}
// stream流只能使用一次
public static void main(String[] args) {
List<Student> list=InitData.getList();
Stream<Student>studentStream= list.stream();
studentStream.forEach(System.out::println);
studentStream.forEach(System.out::println); // 会抛异常
}
public static void main(String[] args) {
List<Student> list=InitData.getList();
// 使用map获取所有学生分数
List<Integer> scoreList=list.stream()
.map(Student::getScore)
.collect(Collectors.toList());
System.out.println(scoreList);
// 使用map获取姓名长度
List<Integer> len=list.stream()
.map(Student::getName)
.map(String ::length)
.collect(Collectors.toList());
System.out.println(len);
// 将每人分数-10
List<Integer> score10List=list.stream()
.map(Student::getScore)
.map(integer -> integer-10)
.collect(Collectors.toList());
System.out.println(score10List);
// 计算分数总和
int count=list.stream()
.map(Student::getScore)
.reduce(0,(a,b)->a+b);
System.out.println(count);
// 计算分数总和
Optional<Integer> count1=list.stream()
.map(Student::getScore)
.reduce((a,b)->a+b);
System.out.println(count1.get());
// 计算最高分
Optional<Integer> max=list.stream()
.map(Student::getScore)
.reduce(Integer::max);
System.out.println(max.get());
// 计算最低分
Optional<Integer> min=list.stream()
.map(Student::getScore)
.reduce(Integer::min);
System.out.println(min.get());
// list.stream().reduce(Comparator.comparing())
}
public static void main(String[] args) {
List<Student> list = InitData.getList();
int sum = list.stream().mapToInt(Student::getScore).sum();
System.out.println(sum);
// 计算平均分
OptionalDouble avg = list.stream().mapToInt(Student::getScore).average();
System.out.println(avg.getAsDouble());
// 生成数组
IntStream is = IntStream.rangeClosed(1, 100);// closed 包含边界
// 计算1-100之间偶数的个数
long l= IntStream.rangeClosed(1, 100)
.filter(s -> s % 2 == 0)
.count();
System.out.println(l);
}
public static void main(String[] args) {
// 使用stream的of方法
String[] arr = {"i", "love", "this", "game"};
Stream.of(arr).map(String::toUpperCase).forEach(System.out::println);
// 使用Arrays.stream
int[] nums = {2, 3, 7, 5};
int a = Arrays.stream(nums).sum();
System.out.println(a);
// 使用函数 从零开始一直创建偶数,取前10个
Stream.iterate(0,n -> n + 2).limit(10).forEach(System.out::println);
}