1.Lambda表达式
1.lambda表达式入门
public class Begin {
public static void main(String[] args) {
//匿名内部类方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程启动了");
}
}).start();
//lambda表达式
new Thread(()-> System.out.println("多线程2启动了")).start();
}
}
2.lambda表达式无参数无返回值
public interface MyInter {
public void run();
}
public class Main {
public static void main(String[] args) {
useMyInter(()-> System.out.println("Myinter.run"));
useMyInter(new MyInter() {
@Override
public void run() {
System.out.println("Myinter.run2");
}
});
}
private static void useMyInter(MyInter myInter){
myInter.run();
}
}
()-> System.out.println("Myinter.run")只是赋予了接口函数的结构,并创建了实例.
但是并没有调用函数run();
3.lambda表达式有参数无返回值
(String s) -> { System.out.println(s);}声明了结构、
public class Main {
public static void main(String[] args) {
getRun((String s) -> { System.out.println(s);},"lambda执行了");
getRun(new FunctionProgramm() {
@Override
public void run(String name) {
System.out.println(name);
}
},"匿名内部类执行了");
}
private static void getRun(FunctionProgramm functionProgramm,String name){
functionProgramm.run(name);
}
}
@FunctionalInterface
public interface FunctionProgramm {
public void run(String name);
}
4.lambda表达式有参数有返回值
public class Main {
public static void main(String[] args) {
getRun((String s) -> {return s;},"lambda执行了");
getRun(new FunctionProgramm() {
@Override
public String run(String name) {
return name;
}
},"匿名内部类执行了");
FunctionProgramm stringStringFunction = (String s) -> {
return s ;
};
getRun(stringStringFunction,"lambda");
}
private static void getRun(FunctionProgramm functionProgramm,String name){
String run = functionProgramm.run(name);
System.out.println(run);
}
}
@FunctionalInterface
public interface FunctionProgramm {
public String run(String name);
}
5.lambda注意事项,lambda表达式与匿名内部类的区别
2.接口
1.接口的默认方法,静态方法
默认方法只用default关键字,可以在接口中写入方法体.
可以被重写,重写的时候去掉default关键字
默认方法只用static关键字,可以在接口中写入方法体.
静态方法只能通过接口名调用,不能引入正常方法,而正常方法可以引入静态方法
public interface MyInterface {
public void show1();
public static void show2(){
System.out.println("静态方法执行了");
};
public default void show3(){
System.out.println("默认方法执行了");
}
}
public class MyInterfaceSon implements MyInterface{
@Override
public void show1() {
System.out.println("普通方法执行了");
}
}
public class Main {
public static void main(String[] args) {
MyInterface son = new MyInterfaceSon();
son.show1();
MyInterface.show2();
son.show3();
}
}
2.函数式接口
3.lambda表达式作为参数
Runnable runnable = ()-> System.out.println("多线程2启动了") ;
多线程2与多线程3原理一样
public class Begin {
public static void main(String[] args) {
//匿名内部类方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程启动了");
}
}).start();
//lambda表达式
new Thread(()-> System.out.println("多线程2启动了")).start();
Runnable runnable= () -> System.out.println("多线程3启动了");
new Thread(runnable).start();
}
}
4.lambda表达式作为返回值
public class Main {
public static void main(String[] args) {
MyInterface anInterface = getInterface();
anInterface.get();
System.out.println(anInterface);
}
private static MyInterface getInterface(){
return ()-> System.out.println("zhang");
}
}
@FunctionalInterface
public interface MyInterface {
public void get();
}
MyInterface anInterface = getInterface(); =>> MyInterface anInterface = ()-> System.out.println("zhang");
5.常用的函数式接口
Consumer
<T>
:消费型接口Supplier
<T>
: 供给型接口Function
<T,R>
: 函数型接口Predicate
<T>
: 断言型接口
1.消费型接口
Consumer
<T>
:消费型接口抽象方法: void accept(T t),接收一个参数进行消费,但无需返回结果。
默认方法: andThen(Consumer<? super T> after),先消费然后在消费,先执行调用的accept方法,然后在执行andThen方法参数after中的accept方法。
public class MySupplier { public static void main(String[] args) { Consumer<String> consumer= (t)->{ System.out.println(t); }; consumer.accept("consumer"); Consumer<String> consumer1=(t)->{ System.out.println(t+"1"); }; consumer.andThen(consumer1).accept("consumer"); }}
2.供给型接口
Supplier
<T>
: 供给型接口抽象方法:T get(),无参数,有返回值。
public class MySupplier { public static void main(String[] args) { Supplier<String> supplier = () -> {System.out.println("Supplier"); return null; }; supplier.get(); }}
3.函数型接口
Function
<T,R>
: 函数型接口抽象方法: R apply(T t),传入一个参数,返回想要的结果。
默认方法:compose(Function<? super V, ? extends T> before),先执行compose方法参数before中的apply方法,然后将执行结果传递给调用compose函数中的apply方法在执行 简单来说:先执行function2 在执行 function1
andThen(Function<? super R, ? extends V> after),先执行调用andThen函数的apply方法,然后在将执行结果传递给andThen方法after参数中的apply方法在执行。它和compose方法整好是相反的执行顺序
先执行function1 在执行 function2
Function<String,String> function= (s1)->{return s1+"Function";}; function.apply("run"); Function<Integer,Integer> function1 = (s2)->{ return s2+2; }; Function<Integer,Integer> function2 = (s2)->{ return s2*2; }; int apply = function1.compose(function2).apply(20); System.out.println(apply); System.out.println(function1.andThen(function2).apply(20));
4.断言型接口
Predicate
<T>
: 断言型接口抽象方法: boolean test(T t),传入一个参数,返回一个布尔值。
negate(),这个方法的意思就是取反
Predicate<Integer> predicate1= (int1)->{if (int1>0) { { return true; } } return false; }; Predicate<Integer> predicate2= (int1)->{if (int1>10) { { return true; } } return false; }; System.out.println(predicate1.test(1)); System.out.println(predicate1.and(predicate2).test(5)); System.out.println(predicate1.or(predicate2).test(5)); System.out.println(predicate1.negate().test(1));
6.stream流
Stream 就好像一个高级的迭代器,但只能遍历一次,就好像一江春水向东流;在流的过程中,对流中的元素执行一些操作,比如“过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等.
流的操作可以分为两种类型:
1)中间操作,可以有多个,每次返回一个新的流,可进行链式操作。
2)终端操作,只能有一个,每次执行完,这个流也就用光光了,无法执行下一个操作,因此只能放在最后。
1.创建stream流方式
//conllection
List<String> strings = new ArrayList<>();
strings.add("zhang");
strings.add("zhang");
strings.add("junjie");
strings.add("li");
strings.add("zhanwei");
strings.stream().forEach(System.out::println);
//Map
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("zhang","junjie");
hashMap.put("li","zhanwei");
Stream<String> stream = hashMap.keySet().stream();
Stream<String> stream1 = hashMap.values().stream();
Stream<Map.Entry<String, String>> stream2 = hashMap.entrySet().stream();
//数组
String[] array={"zhang","junjie","li","zhanwei"};
Stream<String> array1 = Stream.of(array);
2. 中间操作
public class MainTest {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("zhang");
strings.add("zhang");
strings.add("junjie");
strings.add("li");
strings.add("zhanwei");
for (String string : strings) {
if(string.startsWith("zhang")){
System.out.println(string);
}
}
//filter 为过滤操作
strings.stream().filter(s -> s.startsWith("li")).forEach(s-> System.out.println(s));
System.out.println("-----------------------------");
//limit 为拿到前几位
strings.stream().limit(2).forEach(s-> System.out.println(s));
System.out.println("-----------------------------");
//skip 为跳过前几位
strings.stream().skip(2).forEach(s-> System.out.println(s));
System.out.println("-----------------------------");
//limit与skip 综合使用
strings.stream().skip(1).limit(2).forEach(System.out::println);
System.out.println("-----------------------------");
//concat将两个流合并起来
Stream<String> limit1= strings.stream().limit(2);
Stream<String> limit2= strings.stream().limit(3);
Stream.concat(limit1,limit2).forEach(System.out::println);
System.out.println("-----------------------------");
//distinct 去重
strings.stream().limit(2).distinct().forEach(s-> System.out.println(s));
System.out.println("-----------------------------");
//sorted 排序
strings.stream().sorted().forEach(System.out::println);
System.out.println("-----------------------------");
//包含function接口
strings.stream().map(s -> {return s+"Function";}).forEach(System.out::println);
ArrayList<Integer> array = new ArrayList<>();
array.add(10);
array.add(20);
array.add(30);
array.add(40);
array.add(50);
IntStream intStream = array.stream().mapToInt(s -> {
return s;
});
System.out.println(intStream.sum());
}
}
3.终端操作
long count = strings.stream().count();
System.out.println(count);