赞
踩
Oracle甲骨文公司于2015年1月15日发布了新一版JDK8,新版本加入了许多新的特性。这些特性带来了一些改变,可以很大方便Java程序的编写。新特性主要涉及:对于JDK7中Fork/Join并行处理的升级;支持Lambda表达式;添加了Stream API;对于注解的拓展,加入了类型注解、重复注解;在G1回收器中支持字符串去重;内存空间中删除了永久代,引入了元空间。
java8中引入了一个新的操作符“->”,该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆成两部分:
注意:
语法格式:
语法格式1:无参数,无返回值 ()->System.out.println(‘hello Lambda!’)
语法格式2:有一个参数,无返回值 (x)->System.out.println(x);
语法格式3:若只有一个参数,小括号可以省略不写 x->System.out.println(x);
语法格式4:有两个以上的参数,有返回值,并且Lambda体中有多条语句
语法格式5:若Lambda体只有一条语句,return 和大括号都可以省略不写
语法格式6:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即类型推断
Consumer:消费型接口
void accept(T t);
至于具体怎么消费(使用),需要自定义
andThen:
Consumer接口的默认方法andThen
作用:需要两个Consumer接口,可以把两个Consumer接口组合到一起,在对数据进行消费
//消费型接口Consumer
@Test
public void test3() {
happy(300, m -> System.out.println("每次消费:" + m + "元"));
}
private void happy(double money, Consumer<Double> consumer) {
consumer.accept(money);
}
Supplier:供给型接口
T get();
Supplier接口被称之为生产型接口,指定接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据
//供给型接口Supplier @Test public void test4() { List<Integer> list = randomInts(10, () -> (int) (Math.random() * 100)); for (Integer i : list) { System.out.println(i); } } private List<Integer> randomInts(int n, Supplier<Integer> supplier) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < n; i++) { list.add(supplier.get()); } return list; }
Function:函数型接口 接口用来根据一个类型的数据得到另一个类型的数据,
前者称为前置条件,后者称为后置条件
R apply(T t); Function接口中最主要的抽象方法为:R apply(T t),根据类型T的参数获取类型R的结果。
@Test
public void test5() {
String s = "hello world! ";
String s1 = strHandle(s, (str) -> str.trim());
System.out.println("去空格:" + s1);
String s2 = strHandle(s, str -> str.substring(1));
System.out.println(s2);
}
public String strHandle(String s, Function<String, String> function) {
return function.apply(s);
}
Predicate接口
作用:对某种数据类型的数据进行判断,结果返回一个boolean值
Predicate接口中包含一个抽象方法:
boolean test(T t):用来对指定数据类型数据进行判断的方法
结果:
符合条件,返回true
不符合条件,返回false
// 断言型接口Predicate @Test public void test6() { List<String> list = Arrays.asList("hello", "hehehe", "heiheihei", "haha", "wuwu", "enen", "yiyiyi"); // 集合中小于6的字符串 List<String> len_lt6 = filterStrs(list, (s) -> s.length() < 6); for (String s : len_lt6) { System.out.println(s); } } public List<String> filterStrs(List<String> strs, Predicate<String> predicate) { List<String> list = new ArrayList<>(); for (String str : strs) { if (predicate.test(str)) { list.add(str); } } return list; }
若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”(可以理解为方法引用是Lambda表达式的另一种表现形式)
语法格式:
对象::实例方法名
类::静态方法名
类::实例方法名
@Test
public void test1(){
Consumer c1 = (x)->System.out.println(x);
Consumer c2 = System.out::println;
PrintStream printStream = System.out;
Consumer c3 = printStream::println;
}
注意:
1、Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
2、若Lambda参数列表中的第一参数是 实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method
@Test
public void test2(){
BiPredicate<String,String> biPredicate = (x,y)->x.equals(y);
BiPredicate<String,String> biPredicate2 = String::equals;
}
格式: ClassName::new
注意: 需要调用的构造器的参数列表要与函数式接口中的抽象方法的参数列表保持一致!
// 无构造参数的情况 @Test public void test3(){ Supplier<Employee> supplier = ()->new Employee(); Supplier<Employee> supplier2 = Employee::new; System.out.println(supplier.get()); System.out.println(supplier2.get()); } // 一个构造参数的情况,类型推断 @Test public void test4(){ Function<String,Employee> function = (name)->new Employee(name); Function<String,Employee> function2 = Employee::new; System.out.println(function.apply("zhangsan")); System.out.println(function2.apply("zhangsan")); }
格式: Type[]::new
@Test
public void test5(){
Function<Integer,String[]> function = (n)->new String[n];
Function<Integer,String[]> function2 =String[]::new;
System.out.println(function.apply(10).length);
System.out.println(function2.apply(20).length);
}
特性:
Optional类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。
Optional.of:创建一个容器实例
Optional.ofNullable:创建一个容器实例(推荐)
orElse:获取容器内部元素,没有元素返回默认值
orElseGet:获取容器内部元素,没有元素返回默认值(推荐)
map:如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty();
flatMap:与map类似,返回的对象必须是Optional
相关实体类:
public class Girl { private String name; @Override public String toString() { return "Girl{" + "name='" + name + '\'' + '}'; } public Girl() { } public Girl(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Boy { private Girl girl; public Girl getGirl() { return girl; } public void setGirl(Girl girl) { this.girl = girl; } public Boy() { } public Boy(Girl girl) { this.girl = girl; } } public class BoyNew { private Optional<Girl> girl = Optional.empty(); public Optional<Girl> getGirl() { return girl; } public void setGirl(Optional<Girl> girl) { this.girl = girl; } public BoyNew() { } public BoyNew(Optional<Girl> girl) { this.girl = girl; } }
测试论证:
@Test public void test3() { Boy boy = new Boy(); System.out.println("女朋友是:" + getGirlName(boy)); Boy boy2 = new Boy(new Girl("玛利亚")); System.out.println("女朋友是:" + getGirlName(boy2)); BoyNew boyNew = new BoyNew(); System.out.println("女朋友是:" + getGirlName2(boyNew)); BoyNew boyNew2 = new BoyNew(Optional.ofNullable(new Girl("松岛"))); System.out.println("女朋友是:" + getGirlName2(boyNew2)); } public String getGirlName2(BoyNew boy) { return Optional.ofNullable(boy) .orElse(new BoyNew()) .getGirl() .orElse(new Girl("波多")) .getName(); } public String getGirlName(Boy boy) { if (boy != null) { Girl girl = boy.getGirl(); if (girl != null) { return girl.getName(); } } return "波多"; }
具体可参考:JDK8时间日期API
@Test public void test4(){ LocalDate localDate = LocalDate.now(); System.out.println(localDate); LocalTime localTime = LocalTime.now(); System.out.println(localTime); LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime); System.out.println(localDateTime.getYear()); System.out.println(localDateTime.getMonthValue()); System.out.println(localDateTime.getDayOfMonth()); System.out.println(localDateTime.getHour()); System.out.println(localDateTime.getMinute()); System.out.println(localDateTime.getSecond()); } @Test public void test5(){ LocalDateTime localDateTime = LocalDateTime.now(); DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); System.out.println(sdf.format(localDateTime)); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。