1. 接口默认方法 default关键字.
在我们的认知中,以前java中的接口都是抽象方法, jdk1.8中增加了具体实现的默认方法,如下:
//函数式接口
@FunctionalInterface
public interface Mouse {
public String say(String talk);
//接口的默认方法实现
default String eat() {
return "eat something";
}
}
2. 函数式编程: 接口中默认一种抽象方法, 并用注解@FunctionalInterface注解标注, 这样的接口我们就可以用lambda表达式调用了. 增加这个注解以后, 编译器会自动识别接口中的方法是否唯一, 如果有多个参数就会报错, 提示你要写一个抽象方法.
代码如上
3. lambda表达式
lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在lambda 内部修改定义在域外的局部变量,否则会编译错误。
jdk1.8中增加了lambda表达式, 这种写法更加简洁了代码, 一行代码即可搞定, lambda表达式引入 -> 符号, 符号左面是接口方法中的默认参数, 空参数 则用()即可,多参数 可以用(String x, String y ...), ()中的参数也可以缩略简写成 (x,y ...), 以前接口创建对象时需要重写方法, 写法如下
public void lambdaTest() {
Runnable rb = new Runnable() {
@Override
public void run() {
System.out.println("hello world ");
}
};
rb.run();
}
用lambda表达式后的写法
@Test
public void lambdaTest1() {
Runnable rb = () -> System.out.println("hello world");
rb.run();
}
第一种 lambda表达式的写法,无参数
Thread th = new Thread( () -> System.out.println(System.currentTimeMillis()));
th.start();
第二种 1个参数的写法
Stream.iterate(0, x -> x+1).limit(100).forEach(System.out::println);
第三种
/**
* lambda表达式 接口和default接口方法用法
*/
@Test
public void mouseTest() {
Mouse mouse = (x) -> x.toUpperCase();
System.out.println(mouse.say("wangjc say what fuck"));
System.out.println(mouse.eat());Runnable rnb = () -> {
int count = 0;
while (true) {
count++;
if (count > 100) {
break;
}
System.out.println("now : " + System.currentTimeMillis());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(rnb);
th.start();
}
4. 方法和构造函数的引用
首先是构造方法的引用, 写法为 类名::new , 这样会让jdk直接找到默认的 构造函数, 如果没有默认构造函数的话是不可以使用的. 例如
Supplier<StringBuffer> sb = StringBuffer::new;
StringBuffer stringBuffer = sb.get();
然后是方法引用, 类名::方法名
Stream<Double> generate = Stream.generate(() -> Math.random());
generate.limit(5).forEach(System.out::println);
最后是对象引用, 对象名称::方法名
Supplier<StringBuffer> sb = StringBuffer::new;
StringBuffer stringBuffer = sb.get();Stream<Double> generate = Stream.generate(() -> Math.random());
generate.limit(5).forEach(stringBuffer::append );
5. Stream 流, jdk 8 中 新增的stream流, Steam API极大得简化了集合操作.
下列代码是stream的四种获取方式
List<String> strList = new ArrayList<>();
Stream<String> stream = strList.stream();
// 2. 通过Arrays中的静态方法stream()获取数组流
Employee[] emps = new Employee[10];
Stream<Employee> stream1 = Arrays.stream(emps);
// 3. 通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("hello", "wangjc", "world");
// 4.生成
Stream<Double> generate = Stream.generate(() -> Math.random());
下面是具体的stream的使用demo
@Test
public void streamTest1() {
Stream<Employee> stream = list.stream();
Supplier<StringBuffer> sb = StringBuffer::new;
StringBuffer stringBuffer = sb.get();
stream.filter(p -> p.getAge() >= 20)
.sorted((emp1, emp2) -> {
if (emp1.getAge() > emp2.getAge()) {
return 1;
} else {
return 2;
}
})//limit(5) 是只去流中的5条数据 生成新的流返回, forEach()是开始循环处理
.limit(5).forEach(stringBuffer::append);
System.out.println(stringBuffer.toString());
}
class Employee {
private String userName;
private String userId;
private int age;
public Employee() {
}public Employee(String userName, String userId, int age) {
this.userId = userId;
this.userName = userName;
this.age = age;
}public String getUserName() {
return userName;
}public void setUserName(String userName) {
this.userName = userName;
}public String getUserId() {
return userId;
}public void setUserId(String userId) {
this.userId = userId;
}public int getAge() {
return age;
}public void setAge(int age) {
this.age = age;
}public String toString() {
return "username:" + this.userName + "|userid:" + this.userId + "|age:" + this.getAge() + "; hashCode:"
+ this.hashCode();
}
}
在学习下一个例子之前,还需要记住一些steams的知识点。Steam之上的操作可分为中间操作和晚期操作。
中间操作会返回一个新的steam——执行一个中间操作(例如filter)并不会执行实际的过滤操作,而是创建一个新的steam,并将原steam中符合条件的元素放入新创建的steam。
晚期操作(例如forEach或者sum),会遍历steam并得出结果或者附带结果;在执行晚期操作之后,steam处理线已经处理完毕,就不能使用了。在几乎所有情况下,晚期操作都是立刻对steam进行遍历。
steam的另一个价值是创造性地支持并行处理(parallel processing)。
最后,正如之前所说,Steam API不仅可以作用于Java集合,传统的IO操作(从文件或者网络一行一行得读取数据)可以受益于steam处理,这里有一个小例子:
final Path path = new File( filename ).toPath();
try( Stream< String > lines = Files.lines( path, StandardCharsets.UTF_8 ) ) {
lines.onClose( () -> System.out.println("Done!") ).forEach( System.out::println );
}
本文深入探讨Java 8中的新特性,包括接口默认方法、函数式编程、lambda表达式、方法引用、构造函数引用、Stream流操作等,通过实例演示如何使用这些新特性简化代码,提高开发效率。
151

被折叠的 条评论
为什么被折叠?



