1、接口里面不仅可以有抽象方法,还可以有默认方法
\quad
默认方法需使用default
关键字修饰。接口中除了可以定义抽象方法,还可以定义静态常量和静态方法,java8以后还可以定义默认方法。接口中方法都是public
的,故而可以省略public
不写。如下例子:
public interface Formula {
// 静态常量
static final String s = "Hello";
// 静态方法
static void say(){
System.out.println("Hello");
}
// 抽象方法
double calculate(int a);
// 默认方法,Java8以后有
default double sqrt(int a){
return Math.sqrt(a);
}
}
public class Main {
public static void main(String[] args) {
System.out.println(Formula.s); // Hello
Formula.say(); // Hello
Formula formula = new Formula() {
@Override
public double calculate(int a) {
return a * 2;
}
};
System.out.println(formula.calculate(4)); // 8
System.out.println(formula.sqrt(4)); // 2
}
}
2、lambda表达式
什么是函数式接口?
\quad
如果一个接口中只有一个抽象方法(可以有多个默认方法),则这个方法可以完整地代表这个接口,这样的接口称为函数式接口。函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。
\quad
上面给出的接口Formula
就只有一个抽象方法,因此是函数式接口,可以用lambda表达式简化。
\quad
lambda表达式语法:(参数列表) -> {方法体}
。注意:参数类型可以省略;如果方法体只有一句话,大括号可以不写,并省略return。如果参数只有一个,则可以省略括号。
public class lambdaTest {
public static void main(String[] args) {
Formula formula1 = new Formula() {
@Override
public double calculate(int a) {
return a * 2;
}
};
System.out.println(formula1.calculate(4));
Formula formula2 = (int a) -> { return a * 2; };
System.out.println(formula2.calculate(4));
Formula formula3 = a -> {return a * 2;};
System.out.println(formula3.calculate(4));
Formula formula4 = a -> a * 2;
System.out.println(formula4.calculate(4));
}
}
排序场景中重写Comparator
public class test1 {
public static void sort1(){
List<Integer> arr = new ArrayList<>();
arr.add(1); arr.add(3); arr.add(2);
// 正常实现比较函数接口
Collections.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
System.out.println(arr);
}
public static void sort2(){
List<Integer> arr = new ArrayList<>();
arr.add(1); arr.add(3); arr.add(2);
// 使用标准得lambda表示进行简化 (参数列表)->{方法体}
Collections.sort(arr, (Integer o1, Integer o2)->{return o2-o1;});
System.out.println(arr);
}
public static void sort3(){
List<Integer> arr = new ArrayList<>();
arr.add(1); arr.add(3); arr.add(2);
// 若方法体只有return语句则可以省略{}和return
Collections.sort(arr, (Integer o1, Integer o2)->o2 - o1);
System.out.println(arr);
}
public static void sort4(){
List<Integer> arr = new ArrayList<>();
arr.add(1); arr.add(3); arr.add(2);
// 可以省略参数类型
Collections.sort(arr, (o1, o2)->o2 - o1);
System.out.println(arr);
}
public static void main(String[] args) {
sort1();
sort2();
sort3();
sort4();
}
}
3、流式数据stream处理
\quad 看一下示例代码就行,很简单。
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 4, 8, 16, 1, 2);
// 将list中每个元素减去1 并返回
List<Integer> res = list.stream().map(item -> item - 1).collect(Collectors.toList());
System.out.println(res);
// 将list中小于5的数据打印出来
list.stream().filter(item -> item < 5).forEach(item -> System.out.println(item));
// 将list中数据降序排列,并输出
list.stream().sorted((a, b) -> b - a).forEach(item -> System.out.println(item));
// 输出list中元素范围在4-8范围内数个个数
long count = list.stream().filter(item -> item >= 4 && item <= 8).count();
System.out.println(count);
// 输出list去重后的列表
List<Integer> collect = list.stream().distinct().collect(Collectors.toList());
System.out.println(collect);
}
}
4、并行流
使用普通stream
public class ParrelStream {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
for(int i = 0; i < 10000000; i ++ ){
nums.add(i);
}
long begin = System.currentTimeMillis();
List<Integer> collect = nums.stream().sorted().collect(Collectors.toList());
long end = System.currentTimeMillis();
long time = end - begin;
System.out.println("stream cost time: " + time);
}
}
使用并行stream
public class ParrelStream {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
for(int i = 0; i < 10000000; i ++ ){
nums.add(i);
}
long begin = System.currentTimeMillis();
List<Integer> collect = nums.parallelStream().sorted().collect(Collectors.toList());
long end = System.currentTimeMillis();
long time = end - begin;
System.out.println("stream cost time: " + time);
}
}