❤写在前面
❤博客主页:努力的小鳴人
❤系列专栏:JavaSE超详总结
❤欢迎小伙伴们,点赞关注收藏一起学习!
❤如有错误的地方,还请小伙伴们指正!
系列传送门:JavaSE超详总结
【14章Java反射机制】Java Reflection【热榜】
【13章网络编程】鲜为人知网络编程【热榜】
【12章 Java IO流】程序员必看 IO流 详解【热榜】
【附章5计算机字符编码】多种字符编码集的说明【热榜】
Java 8 是 Java 语言开发的一个主要版本,oracle公司于2014年3月发布,是自Java 5 以来最具革命性的版本,Java 8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性
在Java 8中使用 @Repeatable 注解定义重复注解
在某些情况下,我们希望将相同的注释应用于声明或类型使用,从 Java SE 8 版本开始,重复注释能够做到这一点。
如:正在编写代码以使用计时器服务,该服务使您能够在给定时间或按特定时间表运行方法,类似于 UNIX cron服务。现在您想设置一个计时器来在每月的最后一天和每个星期五晚上 11:00运行方法doPeriodicCleanup@Schedule 。要设置计时器运行,请创建一个注释并将其两次应用于doPeriodicCleanup方法。第一次使用指定该月的最后一天,第二次指定周五晚上 11 点
如以下代码示例所示:
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
公共无效 doPeriodicCleanup() { ... }
允许定义枚举时使用@Target(ElementType.TYPE_USE)修饰,这种注解被称为Type Annotation(类型注解)
Java 8为ElementType枚举增加了TYPE_PARAMETER、TYPE_USE
两个枚举值
●ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中
●ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@interface MyAnnotation {}
Stream API 把真正的函数式编程风格引入到Java中
//返回一个顺序流
default Stream<E> stream()
//返回一个并行流
default Stream<E> parallelStream()
stream()
可以获取数组流://返回一个流
static <T> Stream<T> stream(T[] array)
//重载形式,能够处理对应基本类型的数组:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
of()
, 通过显示值创建一个流//返回一个流
public static<T> Stream<T> of(T... values)
Stream.iterate() 和 Stream.generate()
,创建无限流//迭代
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
//生成
public static<T> Stream<T> generate(Supplier<T> s)
创建无限流举例:
public void test4() {
// 迭代
Stream<Integer> stream = Stream.iterate(0, x -> x + 2);
stream.limit(10).forEach(System.out::println);
// 生成
Stream<Double> stream1 = Stream.generate(Math::random);
stream1.limit(10).forEach(System.out::println);
}
多个中间操作可以连接起来形成一个流水线
filter(Predicate p)
接收 Lambda , 从流中排除某些元素distinct()
筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素limit(long maxSize)
截断流,使其元素不超过给定数量skip(long n)
跳过元素,返回一个扔掉了前 n 个元素的流sorted()
产生一个新流,其中按自然顺序排序sorted(Comparator com)
产生一个新流,其中按比较器顺序排序终端操作会从流的流水线生成结果
Functional
只包含一个抽象方法的接口,称为函数式接口
java.util.function
包下定义了Java 8 的丰富的函数式接口@FunctionalInterface .
public interface MyNumber{
public double getValue();
}
//函数式接口中使用泛型:
@FunctionalInterface
public interface MyFun<T>{
public T getValue(T t);
}
作为参数传递 Lambda 表达式
为了将 Lambda 表达式作为参数传递,接收Lambda表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型
最大化减少空指针异常,解决空指针异常
Optional 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表这个值存在
Optional.of(T t)
: 创建一个 Optional 实例,t必须非空;Optional.empty()
: 创建一个空的 Optional 实例Optional.ofNullable(T t)
:t可以为nullboolean isPresent()
: 判断是否包含对象void ifPresent(Consumer super T> consumer)
:如有值,就执行Consumer接口的实现代码且该值会作为参数传给它T get()
: 如果调用对象包含值,返回该值,否则抛异常T orElse(T other)
如果有值则将其返回,否则返回指定的other对象。T orElseGet(Supplier extends T> other)
如果有值则将其返回,否则返回由Supplier接口实现提供的对象T orElseThrow(Supplier extends X> exceptionSupplier)
如果有值则将其返回,否则抛出由Supplier接口实现提供的异常扩展方法
Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default 关键字
interface marla {
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
marla marla = new marla() {
@Override
public double calculate(int a) {
return sqrt(a * 100);
}
};
marla.calculate(100); // 100.0
marla.sqrt(16); // 4.0
marla接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用
请看传送门 >>> 【07章Java常用类】盘点 Java常用类
新的语法,代码更少
Lambda 是匿名函数,Lambda 表达式可以理解为是一段可传递的代码,将代码像数据一样进行传递
语法格式一:无参,无返回值
Runnable r = () -> {System.out.println("I am Lambda!");};
语法格式二:Lambda 需要一个参数,但是没有返回值
Consumer<String> con = (String str) -> {System.out.println(str);};
语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”
Consumer<String> con = (str) -> {System.out.println(str);};
语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略
Consumer<String> con = str -> {System.out.println(str);};
语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值
Comparator<Integer> com = (x,y) -> {System.out.println("实现函数式接口方法!");
Return Integer,compare(x,y);
};
语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略
Comparator<Integer> com = (x,y) -> Interger.compare(x,y);
Runnable r1 = new Runnable(){
@override
public void run(){
System.out.println("Hello Lambda!");
}
}
匿名类到 Lambda 后
Runnable r = () -> {System.out.println("Hello Lambda!");};
Lambda 表达式中的参数类型都是由编译器推断得出的。Lambda表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖上下文环境,是由编译器推断出来的,这就是所谓的 “类型推断”
对开发者最有用的工具
jjs是一个基于标准Nashorn引擎的命令行工具,可以接受js源码并执行
举例:
一个 un.js 文件
function f() {
return 1;
};
print( f() + 3 );
可以在命令行中执行这个命令:jjs un.js,控制台输出结果是:4
官方文档传送门 >>> jjs官方文档
jdeps可以展示包层级和类层级的Java类依赖关系,以.class文件、目录或者jar文件为输入,然后把依赖关系输出到控制台
官方文档传送门 >>> jdeps官方文档
基于新增的lambda表达式和steam特性,Java 8中为java.util.concurrent.ConcurrentHashMap类添加了新的方法来支持聚焦操作;另外,也为java.util.concurrentForkJoinPool类添加了新的方法来支持通用线程池操
Selector选择器的工作原理
:首先向Selector中注册Channel,然后Selector就可以检测到一个或多个NIO通道,并且能够了解每个通道是否已经做好准备进行读写总结:这Java 8新特性很多,学起来也学不太明白,写写笔记到处请教学习
作者算是一名Java初学者,文章如有错误,欢迎评论私信指正,一起学习~~
如果文章对小伙伴们来说有用的话,点赞关注收藏就是我的最大动力!
不积跬步,无以至千里,书接下回,欢迎再见