什么是函数式编程?
是一种编程模型,把计算机中的运算看做数学中的函数计算,并且避免了状态及变量的概念 f(x)
函数式接口
第一种:就是在一个接口中定义唯一的一个抽象方法,那么这个接口就是函数式接口
public interface FunctionInterfaceDemo {
void sayHello();
}
第二种:通过注解的方式@FunctionalInterface声明,加注解相当于加了一个强制性的约束
@FunctionalInterface
public interface FunctionInterfaceDemo {
void sayHello();
}
函数式接口里面也可以有实现方法,好处是修改接口后不需要改实现,使得接口在发布之后仍然可以升级
@FunctionalInterface
public interface FunctionInterfaceDemo {
void sayHello();
//java8两种实现方法方式
static void sayHi(){
System.out.println("say hi");
}
default void doAnything(){
System.out.println("do anything");
}
}
public class Main {
public static void main(String[] args) {
FunctionInterfaceDemo fi = new FunctionInterfaceDemo() {
@Override
public void sayHello() {
System.out.println("say hello");
}
};
fi.sayHello();
fi.doAnything();
FunctionInterfaceDemo.sayHi();
}
}
重写父类的方法不违背函数式接口的定义
例如重写equals或toString
@FunctionalInterface
public interface FunctionInterfaceDemo {
void sayHello();
//java8两种实现方法方式
static void sayHi(){
System.out.println("say hi");
}
default void doAnything(){
System.out.println("do anything");
}
boolean equals(Object object);
}
Lambda表达式
语法组成:
1. 一个括号内用逗号分隔的形式参数,参数是
函数式接口里面的方法参数
2. 一个箭头号 ->
3. 方法体或者代码块
(parameters) -> expression
public class MainDemo2 {
public static void main(String[] args) {
//传统方式启动一个线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("I am thread test1");
}
}).start();
//Lambda简化后
new Thread(()->{
System.out.println("I am thread test2");
}).start();
//Lambda继续简化,整个代码块只有一行代码,而这一行代码就是表达式的返回值的话就可以省略代码块
new Thread(()-> System.out.println("I am thread test3")).start();
}
}
public class MainDemo3 {
public static void main(String[] args) {
List<String> words = Arrays.asList("a", "b", "c");
//传统方式比较排序
// words.sort(new Comparator<String>() {
// @Override
// public int compare(String o1, String o2) {
// return o2.compareTo(o1);
// }
// });
//Lambda表达式实现
// words.sort((String o1,String o2) -> {
// return o2.compareTo(o1);
// });
//继续优化
words.sort((o1,o2) ->o2.compareTo(o1));
for (String word: words) {
System.out.print(word);
}
}
}
方法引用
1. 引用静态方法 String::valueOf
2. 引用对象的实例方法 x::toString
3.引用某个类型的任意对象的实例方法 String::toString
4.引用类构造函数 String::new
public class PersonInfo implements Comparable<PersonInfo> {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(PersonInfo o) {
return this.getName().compareTo(o.getName());
}
public int compare(PersonInfo p1 , PersonInfo p2){
return p1.getName().compareTo(p2.getName());
}
}
/**
* Created by xingyuchao on 2018/1/19.
* 工厂方法,将PersonInfo包装成函数式接口的方式
*/
public class PersonInfoFactory {
private Supplier<PersonInfo> supplier;
public PersonInfoFactory(Supplier<PersonInfo> supplier){
this.supplier = supplier;
}
public PersonInfo getPerson(){
return supplier.get();
}
}
public class MainDemo4 {
public static void main(String[] args) {
//引用类构造函数 String::new
PersonInfoFactory personInfoFactory = new PersonInfoFactory(PersonInfo::new);
List<PersonInfo> personInfoList = new ArrayList<>();
PersonInfo personInfo1 = personInfoFactory.getPerson();
personInfo1.setName("xingyuchao");
personInfoList.add(personInfo1);
PersonInfo personInfo2 = personInfoFactory.getPerson();
personInfo2.setName("admin");
personInfoList.add(personInfo2);
PersonInfo personInfo3 = personInfoFactory.getPerson();
personInfo3.setName("china");
personInfoList.add(personInfo3);
//传统方式
personInfoList.sort(new Comparator<PersonInfo>() {
@Override
public int compare(PersonInfo o1, PersonInfo o2) {
return 0;
}
});
print(personInfoList);
//引用对象的实例方法 x::toString
//personInfoList.sort(personInfo1::compare);
//引用某个类型的任意对象的实例方法 String::toString
//personInfoList.sort(PersonInfo::compareTo);
//引用静态方法 String::valueOf
personInfoList.sort(MainDemo4::myCompare);
print(personInfoList);
}
public static void print(List<PersonInfo> personInfos){
personInfos.forEach(personInfo -> System.out.print(personInfo.getName()+" "));
System.out.println();
}
private static int myCompare(PersonInfo p1 , PersonInfo p2){
return p1.getName().compareTo(p2.getName());
}
}
流式操作
根据返回结果:分为中间操作和最终操作(flume风格 链式操作)
根据并发性区分: 串行和并行操作
Stream.sequential()
Stream.parallel()
中间操作
Filter过滤器
Sorted 排序
Distinct
SubStream 获取子流
终止操作
forEach
findFirst
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class MainDemo5 {
static List<Person> person = new ArrayList<Person>(){
{
add(new Person("admin",22));
add(new Person("xingyuchao",25));
}
};
public static void main(String[] args) {
// person.forEach(
// person ->{
// person.setAge(person.getAge() + 5);
// System.out.println(person.toString());
// });
// 过滤小于24岁的
person.stream().filter(person -> person.getAge()>24).forEach( person -> System.out.println(person.toString()));
}
}