Java8 是Java一个主要版本。Oracle公司2014年3月18发布。它支持函数式编程,新的JavaScript引擎。新的日期API。新的Stream API等
新特性
1、Lambda表达式 - Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法)
2、方法引用 -方法引用提供了非常有用的语法。可以直接引用已有的Java类或对象的方法或构造器。与Lambda联合使用,方法引用可以是语言构造更紧凑粗简介,减少冗余代码
3、默认方法-默认方法就是在接口里面有一个实现的方法
4、新工具- 新的编译工具,如:Nashorn引擎jjs、类依赖分析器jdeps
5、Stream API 把真正的函数式编程风格引入到Java中
6、Date Time API加强对日期与时间处理
7、Optional类-Optional类已经成为java 8 类库一部分,用来解决空指针异常
8、Nashorn、JavaScript 提供一个新的Nashorn javascript引擎,允许我们在jvm上运行特定的javascript应用
二、实战练习
1、Lambda表达式
public static void main(String[] args) { List<String> names1=new ArrayList<>(); names1.add("Google"); names1.add("Jingdong"); names1.add("Taobao"); names1.add("Tiktok"); names1.add("Sina"); List<String> names2=new ArrayList<>(); names2.add("Google"); names2.add("Jingdong"); names2.add("Taobao"); names2.add("Tiktok"); names2.add("Sina"); Java8Test01 java8Test01=new Java8Test01(); java8Test01.sortUsingJava7(names1); System.out.println(names1); java8Test01.sortUsingJava8(names2); System.out.println(names2); } //java7排序 private void sortUsingJava7(List<String> names){ Collections.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }); } //java8排序 private void sortUsingJava8(List<String> names){ Collections.sort(names,(s1,s2)->s1.compareTo(s2)); }
表达式
①不需要参数,返回值为5 ()->5
②接受一个参数,返回其2倍 x->x*2
③接受2个参数(数字),返回差 (x,y)-> x-y
④接受2个int整形,返回他们的和 (int x,int y)->x+y
⑤接受1个string,在控制台打印,不返回任何值(void) (String s)->System.out.print(s)
public static void main(String[] args) {
MathOpe mathOpe = ()->6;
System.out.println(mathOpe.addtion());
MathAdd mathAdd=(x,y)->x*y;
System.out.println(mathAdd.addtion(1,3));
StringBak stringBak = msg-> System.out.println("字符串"+msg);
stringBak.funs("Hello World");
}
interface MathOpe{
int addtion();
}
interface MathAdd{
int addtion(int a,int b);
}
interface StringBak{
void funs(String s);
}
lambda中使用的变量必须是最终变量,比如final。或者声明后不会被后面修改的值,不然编译不必通过
2、方法引用
public class Car {
private String name;
private int year;
public static Car create(final Supplier<Car> supplier,String name,int year){
name=name;
year=year;
System.out.println("构造器 被引用了");
return supplier.get();
}
public static void collide(final Car car){
System.out.println("Collide 被调用了"+car.toString());
}
public void follow(final Car another){
System.out.println("Following the 被调用了"+another.toString());
}
public void repair(){
System.out.println("Repaired 被调用了"+this.toString());
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", year=" + year +
'}';
}
}
public class MethodTest {
//构造器引用:它的语法是Class::new ,或者更一般的Class<T>::new 示例
//final Car car = Car.createe(Car::new);final List<Car> cars=Arrays.asList(car)
//静态方法引用:他的语法是Class::static_method。实例
//cars.forEach(Car::collide)
//特定类的任意对象的方法引用:他语法是Class::method。实例
//cars.forEach(Car::follow)
//特定对象的方法引用:它的语法是 instance::method。 实例
//final Car police=Car.create(Car::new);cars.forEach(police::follow)
public static void main(String[] args) {
Car car = Car.create(Car::new, "BWM", 2);
List<Car> cars= Arrays.asList(car);
cars.forEach(Car::collide);
cars.forEach(Car::repair);
Car car1=Car.create(Car::new,"BC",3);
cars.forEach(car1::follow);
}
}
3、函数式接口
①自定义函数式接口
@FunctionalInterface
public interface CreateFunction {
void sayMessage(String msg);
}
public class FuncTest {
public static void main(String[] args) {
CreateFunction createFunction = msg->{
System.out.println("hello" +msg);
};
createFunction.sayMessage("fweng");
}
}
②扩展函数式接口 Predicate
Predicate<T> 接口是一个函数式接口。他接受一个输入参数T,返回一个布尔值结果。
该接口包含多种默认方法来将predicate组合成其他复杂逻辑,比如与或非
该接口用于测试对象是 true 或 false
public static void main(String[] args) {
//Predicate<T>
Predicate<Integer> predicate= n->n==2;
System.out.println(predicate.test(3));
List<Integer> list= Arrays.asList(1,2,3,4,5,6,7,8,9);
System.out.println("打印偶数");
Predicate<Integer> predicate1 = n->n%2==0;
compare(list,predicate1);
System.out.println("大于3");
Predicate<Integer> predicate2=n->n>3;
compare(list,predicate2);
}
private static void compare(List<Integer> list,Predicate<Integer> predicate){
for(Integer n:list){
if(predicate.test(n)){
System.out.println(n+" ");
}
}
}
③扩展函数式接口Function
入参是一个参数,返回是一个参数
public static void main(String[] args) {
Function<String, Boolean> function=s1->s1!=null;
Boolean apply=function.apply("123");
System.out.println(apply);//true
Function<Boolean,Integer> function1=s2->s2?1:0;
Function<String, Integer> stringIntegerFunction = function.andThen(function1);
Integer aaa = stringIntegerFunction.apply(null);
System.out.println(aaa);//0
Function<String, Integer> compost=function1.compose(function);
Integer abc=compost.apply("abc");
System.out.println(abc);//1
}
④扩展函数式接口Consumer
接受一个参数,没有返回值
import static java.lang.System.out;
Consumer<String> consumer=out::println;
consumer.accept("sss");
⑤扩展函数式接口Supplier
无参数
public class Student {
private String name;
private Integer age;
Student(String name,Integer age){
this.name=name;
this.age=age;
}
}
Supplier<String > supplier=()->"无参数的";
String s = supplier.get();
out.println(s);
Supplier<Student> supplier1=()->new Student("ZS",12);
Student student=supplier1.get();
student.show();
4、Java8 默认方法
接口可以存在一个默认方法,不通过实现类来实现方法
public interface Animal {
default void add(int a,int b){
System.out.println(a+b);
}
static void blowWorn(){
System.out.println("按喇叭,嘟嘟嘟");
}
}
5、Optional类
可以保存为null对象
Integer val=null;
Optional<Integer> optionalInteger=Optional.ofNullable(val);
// Optional<Integer> optional=Optional.of(val);//会有空指针异常
System.out.println(optionalInteger.isPresent());//null 为false 有值为true
6、Stream流
Java8添加的抽象的流Stream,使用一种类似SQL语句从数据库查询数据的直观方式提供一种对Java集合运算和表达的高阶抽象。Stream可以极大提高Java程序员的生产力,让程序员写出高效率干净简介代码。
这种风格要将处理的元素集合看作一种流,流在管道中运输。并且可以在管道的节点上进行处理,比如筛选、排序、聚合等
元素流在管道中经过中间操作的处理。最后由最终操作得到前面处理的结果。
stream of elements --> filter -->sorted -->map -->collect
代码
List<Integer> integers= Arrays.asList(1,2,3,4,5,6);
// integers.stream()
// .filter(b->b.getColor()==RED) //过滤一些数
// .sorted((x,y)->x.getWeight()-y.getWeight()) //从大到小
// .mapToInt(Widget::getWeight) //对元素进行在加工 比如+1+2
// .sum(); //求和 或者转换成数据等操作
List<Integer> collect3 = integerList.stream()
.filter(x -> x > 0)
.sorted((a, b) -> b-a)
.map(a->a+10)
.collect(Collectors.toList());
System.out.println(collect3);
List<String> strings=Arrays.asList("abc","","bc","dd","","jkl");
//查询空字符串个数
long count = strings.stream()
.filter(x -> x.isEmpty())
.count();
System.out.println(count);
//过滤掉空字符串得到新的列表
List<String> collect = strings.stream()
.filter(x -> !x.isEmpty())
.collect(Collectors.toList());
System.out.println(collect);
//合并字符串
String collect1 = strings.stream()
.filter(x -> !x.isEmpty())
.collect(Collectors.joining(","));
System.out.println(collect1);
List<Integer> integerList=Arrays.asList(1,2,3,4,5,6,7);
//变成平方
List<Integer> collect2 = integerList.stream()
.map(i -> i * i)
.collect(Collectors.toList());
System.out.println(collect2);
//求最大数、最小数、平均数
IntSummaryStatistics intSummaryStatistics = collect2.stream()
.mapToInt(x -> x)
.summaryStatistics();
System.out.println(intSummaryStatistics.getMax());
System.out.println(intSummaryStatistics.getMin());
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::print);
//map修改字段
List<String> result = res.stream().map(o->{
if(StringUtils.equalsIgnoreCase(o.getId(),“12331”))
{
o.setPower(false);
}
return o;
}).collect(Collectors.toList());
7、日期类
LocalDateTime now=LocalDateTime.now();
System.out.println(now);
LocalDate localDate = now.toLocalDate();
System.out.println(localDate);
System.out.println(localDate.getMonth());
ZonedDateTime detel = ZonedDateTime.parse("2022-03-13T19:27:05+11:00[Asia/Shanghai]");
System.out.println("detel:"+detel);
ZoneId id=ZoneId.of("Europe/Paris");
System.out.println("ZoneID:"+id);
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("当前时区:"+currentZone);