函数式编程 lambda+Stream
外部迭代 内部迭代
外部:for循环
内部迭代
求和1
int sum = IntStream.of(nums).sum();
惰性求值
求int数组最小值1
IntStream.of(new int[]{1,2,3,4,5}).min().getAsInt();
改成并行:新建线程池,拆分数组,归并1
IntStream.of(test).parallel().min().getAsInt();
1 | Random random = new Random(1024); |
lambda:1
2
3
4
5
6
7
8
9
10
11Object ok = new Runnable() {
public void run() {
System.out.println("ok");
}
};
new Thread((Runnable)ok).start();
new Thread(()->System.out.println("ok")).start();
Object target3 = (Runnable)()->System.out.println("ok");
new Thread((Runnable)target3);
4种写法1
2
3
4
5
6
7
8
9
interface interface1{
int doubleNum(int i);
}
interface1 i1 = (i)->i*2;
interface1 i2 = i->i*2;
interface1 i3 = (int i)->i*2;
interface1 i4 = (int i)->{return i*2;};
1 | //输入int返回String |
使用JDK8带的函数接口Function
1
2
3
4public void printMoneyJDK8(Function<Integer,String> moneyFormat){
System.out.println("存款:"+moneyFormat.apply(this.money));
}
me.printMoneyJDK8(i->new DecimalFormat("#,###").format(i));
好处:链式操作1
2
3Function<Integer,String> moneyFormat = i->new DecimalFormat("#,###").format(i);
//存款:RMB99,999
me.printMoneyJDK8(moneyFormat.andThen(s->"RMB"+s));
级联表达式和科里化//todo
类型推断2-13 //todo
::方法引用
- 用::将方法名称与类/对象分隔开
1.类::实例方法1
2BiFunction<Dog,Integer,Integer> eatFunc = Dog::eat;
System.out.println("还有"+eatFunc.apply(new Dog(),2 ));
2.类::静态方法 Integer::valueOf
1
2
3
4
5
6
7
8class Dog{
//消费者:输入Dog,输出void
public static void Bark(Dog dog){
System.out.println("bark");
}
}
Consumer<Dog> consumer = Dog::Bark;
consumer.accept(new Dog());
- 对象::实例方法
list::add
静态方法和成员方法的区别:静态方法没有this
JDK默认会将当前实例传给非静态方法,叫this,位置必须第一个。
java里都是传值而不是引用 所以不会空指针1
2
3IntUnaryOperator eat = dog::eat;
dog=null;
System.out.println("还剩下"+eat.applyAsInt(3));
1 | class Dog{ |
- 类::构造方法
ArrayList::new
提供者:输入空,输出是实例1
Supplier<Dog> supplier = Dog::new;
方法:带参构造函数,输入是int,输出是实例1
Function<Integer,Dog> dog2 = Dog::new;
四大核心函数式接口
Consumer
消费者 接收一个值消费掉list.forEach
接收T返回void1
2Consumer<String> consumer = s-> System.out.println(s);
consumer.accept("等待输出");Function<T,R>
接收一个参数返回一个结果1
2
3
4public static String str(String str,Function<String,String> f){
return f.apply(str);
}
String s = str("functionnnntest",(str)-> str.toUpperCase());BiFunction<T, U, R>
R apply(T t, U u);
Supplier
::T get();
不传参数返回结果1
2
3
4
5
6public static List<Integer> getNumber(int num,Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for(int i =0;i<num;i++){
list.add(sup.get());}
return list;}
List<Integer> list = getNumber(10,()->(int)(Math.random()*100));Predicate
::boolean test(T t);
断言1
2
3Predicate<Integer> predicate = i->i>0;
//true
System.out.println(predicate.test(9));
过滤器保留有L的单词1
2
3
4
5
6
7
8
9
10
11private static void predicate(){}
private static List<String> filter(List<String>list,Predicate<String> prd){
List<String> res=new ArrayList<>();
for(String s:list){
if(prd.test(s))res.add(s);
}
return res;
}
List<String> words = Arrays.asList("LL","LB","EE");
//[LL, LB]
List<String> sig = filter(words,(d)->d.contains("L"));
有一些自带的类型接口,不用写泛型,优先使用1
2IntPredicate predicateint = i->i>0;
IntConsumer intConsumer = System.out::println;;
Lambda:函数作为方法的参数
当接口只有一个抽象方法,函数式接口,不会生成class
内部类写法
1
2
3
4
5
6
7interface Ido{ public void doo(String thing);}
class IdoImp implements Ido{
public void doo(String thing){
System.out.println(thing+"adfadfa");}}
//main
IdoImp idoimp = new IdoImp();
idoimp.doo("thing");Lambda写法
1
2interface Ido{ public void doo(String thing);}
Ido ido = (thing)-> System.out.println(thing+"doooooo");比较对象
Comparator<Integer> c = (x,y)->Integer.compare(x,y);
方法引用
1
2
3Arrays.sort(strings,String::compareToIgnoreCase);
Arrays.sort(strings,(x,y)->x.compareToIgnoreCase(y));
System.out.println(Arrays.toString(strings));
- ArrayList 打印全部元素
list.forEach(x->sout(x))
list.forEach(System.out::println)