Java8新特性:
Lambada表达式
不使用labmda表达式:
Comparator<Integer> com1 = new Comparator<Integer>(){
@Override
public int compare(Interger o1, Integer o2){
return Integer.compare(o1,o2);
}
};
int compare1 = com1.compare(12,21);
使用lambda表达式:
```java
Comparator<Integer> com2 = (o1,o2) -> Integer.compare(o1,o2);
int compare2 = com2.comprare(32,21);
Lambda表达式的使用:
举例:(o1,o2) -> Integer.compare(o1,o2);
格式:
- lambda操作符或者箭头操作符
- 左边:lambda形参列表(接口中的抽象方法的形参列表),如果lambda形参只有一个参数,其一对()也可以省略
- 右边:lambda体(重写的抽象方法的方法体),lambda体应该使用一对{}包裹;如果labmda体只有一条执行语句(可能是return语句),可以省略这一对{}和return
格式一:无参无返回值
Runnable r1 = () -> System.out.println("我爱北京天安门");
r1.run();
格式二:Lambda需要一个参数,但是没有返回值
Consumer<String> con1 = (String s) -> { System.out.prinln(s);};
con1.accept("谎言是听的人当真了,誓言是说的人当真了”);
格式三:数据类型可以省略,可以由编译器推断得出,称为“类型推断”
ArrayList<String> list = new ArrayList<>(); // 类型推断1
int[] arr = {1,2,3} // 类型推断2
格式四:Lambda若只需要一个参数时,选举是的小括号可以省略
Consumer<String> con2 = s -> {System.out.println(s);};
格式五: Lambada需要两个或两个以上的参数,多条执行语句,并且可以有返回值
Comparator<Integer> com2 = (o1,o2) -> {
sout(o1);
sout(o2);
return o1.comparaTo(o2);};
System.out.println(com2.compare(12,6));
语法格式六:当Lambda体只有一条语句时,return与大括号若有,都可以省略
Comparator<Integer> com3 = (o1,o2) -> o2 ;
函数式接口
- Lambda表达式中只可以利用接口实现,然后要求接口只能有一个抽象方法。
- Lambda表达式的本质:作为函数式接口的实例
- 如果一个接口中,只声明了了一个抽象方法,则此接口就称为函数式接口,使用@FunctionInterface进行注解。
Java中的四大核心函数式接口:
消费型接口代码举例:
public void happyTime(double money, Consumer<Double> con){
con.accept(money);
}
// 传统匿名对象方法调用上面函数:
happyTime(300, new Consumer<Double>(){
@Override
public void accept(Double mon){
System.out.println("矿泉水一瓶卖" + mon);
}
});
// Lambda函数实现调用上述函数:
happyTime(300, mon -> System.out.println("矿泉水一瓶卖" + mon));
断定型接口的用法:
public List<String> filterSTring(List<String> list, Predicate<String> pre){
ArrayList<String> filterList = new ArrayList<>();
for(String s: list){
if(pre.test(s)){
filterList.add(s);
}
return filterList;
}
List<String> list = Arrays.asList("北京","南京","天津","东京","西京","普京");
// 传统匿名实现接口
List<String filterStrs = filterString(list, new Predecate<String>(){
public boolean test(String s){
return s.contains("京");
}
}
// Lambda实现接口
List<String> filterStr1 = filterString(list, s -> s.contains("京"));
// 输出结果
Systm.out.prinln(filterStrs1);
方法引用:
Comparator<Integer> com3 = Integer :: compare;
int compare3 = com3.compare(32,21);
方法引用的使用:
- 使用场景:当要传递给Labmda体的操作,已经有实现的方法了,可以使用方法引用!(形参和返回值一样)
- 方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例。所以方法引用,也是函数式接口的实例。
- 使用格式:类(或对象) :: 方法名
使用条件:
- 情况一:对象::实例方法
Consumer中的 void accept(T t)
PrintSTream中的void println(T t)
PrintStream ps = System.out;
Consumer<String> con2 = ps::println;
con2.accept("beijying");
- 情况二:类::静态方法
Comparator中的int compare(T t1,T t2)
Integer中的int compare(T t1, T t2)
Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
Comparator<Integer> com2 = Integer:compare;
Function中的R apply(T t)
Math中的Long round(Double d)
Function<Double,Long> func1 = d -> Math.round(d);
Function<double,Long> func2 = Math::round;
fucn1.apply(12.3);
func2.apply(12.6);
- 情况三:类::实例方法(有难度)
接口函数的第一个参数作为类本身存在了
注意Function的第一个参数为Employee
构造器引用
和方法引用类似,函数式接口的抽象方法的形参和构造器形参列表一致。
抽象方法的返回值类型即为构造器所属的类。
无参构造器:
有一个参数构造器:
两个参数的构造器引用:
数组引用:
并行流和串行流
虽然一些sql类型数据库可以在sql层面来处理,但是还有一些非关系数据库的一些信息需要在java层面来处理
如何创建流
方式一:通过集合
List<Emploee> employees = EmployeeData.getEmployees();
Stream<Employee> stream = employees.stream(); // 创建一个顺序流
Stream<Employee> parallelStream = employees.paralelStream(); // 返回一个并行流
方式二:通过数组
int[] arr = new int[]{1,2,3,4,4};
// 调用Arrays类的static <T> Stream<T> stream(T[] array): 返回一个流
IntStream steam = Arrays.stream(arr);
Employee e1 = new Employee(120,"ttom");
Employee e2 = new Employee(34,"jerry");
Employee[] arr1 = new Employee[]{e1,e2};
Stream<Employee> stream1 = Arrays.stream(arr1);
方式三:通过Stream中的of()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
方式四:创建无限流
// 迭代
Stream.iterate(0,t -> t+2).limit(10).forEach(System.out::prinln):
// 生成
Stream.generate(Math::random).limit(10).forEach(System.out::prinln);