前言

JDK 15公布啦~ 咱们一起回顾JDK 5-15 的新个性吧,大家一起学习哈~

本文曾经收录到github

https://github.com/whx123/Jav...

公众号:捡田螺的小男孩

Java 5 新个性

1. 泛型

泛型实质是参数化类型,解决不确定具体对象类型的问题。

 List<String> strList=new ArrayList<String>();

2. 加强循环(for-each)

for-each循环简化了汇合的遍历。

String [] str = {"关注","公众号","捡田螺的小男孩"};for (String temp:str) {     System.out.println(temp);}

3. 主动封箱拆箱

  • 主动装箱: 就是将根本数据类型主动转换成对应的包装类。
  • 主动拆箱:就是将包装类主动转换成对应的根本数据类型。

包装类型有:Integer,Double,Float,Long,Short,Character和Boolean

Integer i =666;  //主动装箱int a= i;     //主动拆箱

4. 枚举

关键字enum能够将一组具名的值的无限汇合创立为一种新的类型,而这些具名的值能够作为惯例的程序组件应用,这就是枚举类型。

enum SeasonEnum {    SPRING,SUMMER,FALL,WINTER;}

5. 可变参数

咱们在定义方法参数的时候不确定定义多少个,就能够定义为可变参数,它实质上是一个数组

public static void main(String[] args) throws Exception {    String [] str = {"关注","公众号","捡田螺的小男孩"};    testVarargs(str);    String str1 = "关注公众号,捡田螺的小男孩";    testVarargs(str1);}//可变参数String... argsprivate static void testVarargs(String... args) {    for (String arg : args) {        System.out.println(arg);    }}

6. 注解

能够把注解了解为代码里的非凡标记,这些标记能够在编译,类加载,运行时被读取,并执行相应的解决。

@Target(ElementType.METHOD)@Retention(RetentionPolicy.SOURCE)public @interface Override {}

7.动态导入

通过import static类,就能够应用类里的动态变量或办法。看一下例子哈~

import static java.lang.System.out; //动态导入System类的动态变量outpublic class Test {    public static void main(String[] args) throws Exception {        String str1 = "关注公众号,捡田螺的小男孩";        System.out.println(str1); //惯例写法        out.println(str1);  //动态导入,能够间接应用out输入    }}

8. 线程并发库(JUC)

JDK5 丰盛了线程解决性能,java.util.concurrent包提供了以下的类、接口:

  • 线程池:ExecutorService接口
  • 线程护斥:Lock 类
  • 线程通信:Condition接口
  • 同步队列:ArrayBlockingQueue类
  • 同步汇合:ConcurrentHashMap类

Java 6 新个性

1.Desktop类和SystemTray类

JDK 6在java.awt包下,新增了两个类:Desktop类和SystemTray类

  • Desktop类: 用来关上零碎默认浏览器浏览指定的URL,关上零碎默认邮件客户端发邮件等
  • SystemTray类:用来在系统托盘区创立一个托盘程序,如果在微软的Windows上,它被称为“任务栏”状态区域。
//获取Desktop实例Desktop desktop = Desktop.getDesktop();desktop.browse(URI.create("https://www.baidu.com"));

2. 应用JAXB2来实现对象与XML之间的映射

JAXB,即Java Architecture for XML Binding,能够实现对象与XML之间的映射,罕用注解如下:

  • @XmlRootElement:注解在类下面,对应xml的跟元素,应用name属性定义根节点的名称。
  • @XmlElement:指定一个字段或get/set办法映射到xml的节点,应用name属性定义这个根节点的名称。
  • @XmlAttribute:将JavaBean对象的属性映射为xml的属性,应用name属性为生成的xml属性指定别名。
  • @XmlAccessorType:定义映射这个类中的何种类型都须要映射到xml。
  • @XmlSchema: 将包映射到XML名称空间

看个例子吧~

public class JAXB2XmlTest {    public static void main(String[] args) throws JAXBException, IOException {                List<Singer> list = new ArrayList<>();        list.add(new Singer("jay", 8));        list.add(new Singer("eason", 10));        SingerList singerList = new SingerList();        singerList.setSingers(list);        String str = JAXB2XmlTest.beanToXml(singerList, SingerList.class);        String path = "C:\\jay.txt";        BufferedWriter bfw = new BufferedWriter(new FileWriter(new File(path)));        bfw.write(str);        bfw.close();    }    private static String beanToXml(Object obj, Class<?> load) throws JAXBException {        JAXBContext context = JAXBContext.newInstance(load);        Marshaller marshaller = context.createMarshaller();        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);        marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");        StringWriter writer = new StringWriter();        marshaller.marshal(obj,writer);        return writer.toString();    }}public class Singer {    private String name;    private int age;    public Singer(String name, int age) {        this.name = name;        this.age = age;    }    @XmlAttribute(name="name")    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @XmlAttribute(name="age")    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}@XmlRootElement(name="list")public class SingerList {    private List<Singer> singers;        @XmlElement(name="singer")    public List<Singer> getSingers() {        return singers;    }    public void setSingers(List<Singer> singers) {        this.singers = singers;    }}

运行成果:

<?xml version="1.0" encoding="GBK" standalone="yes"?><list>    <singer age="8" name="jay"/>    <singer age="10" name="eason"/></list>

3.轻量级 Http Server API

JDK 6中提供了简略的Http Server API,能够构建嵌入式Http服务器,同时反对Http和Https协定。HttpServer会调用HttpHandler实现类的回调办法来解决客户端申请,这里用户只需实现HttpHandler接口就能够了。

/** * 依据Java提供的API实现Http服务器 */public class MyHttpServer {    /**     * @param args     * @throws IOException     */    public static void main(String[] args) throws IOException {        //创立HttpServer服务器        HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 10);        //将 /jay申请交给MyHandler处理器解决        httpServer.createContext("/", new MyHandler());        httpServer.start();    }}public class MyHandler implements HttpHandler {    public void handle(HttpExchange httpExchange) throws IOException {        //申请头        Headers headers = httpExchange.getRequestHeaders();        Set<Map.Entry<String, List<String>>> entries = headers.entrySet();        StringBuffer response = new StringBuffer();        for (Map.Entry<String, List<String>> entry : entries){            response.append(entry.toString() + "\n");        }        //设置响应头属性及响应信息的长度        httpExchange.sendResponseHeaders(200, response.length());        //取得输入流        OutputStream os = httpExchange.getResponseBody();        os.write(response.toString().getBytes());        os.close();    }}

4. 插入式注解解决API

JDK 6提供了插入式注解解决API,能够让咱们定义的注解在编译期而不是运行期失效,从而能够在编译期批改字节码。lombok框架就是应用该个性来实现的,Lombok通过注解的形式,在编译时主动为属性生成结构器、getter/setter、equals、hashcode、toString等办法,大大简化了代码的开发。

5. STAX

STAX,是JDK6中一种解决XML文档的API。

public class STAXTest {    public static void main(String[] args) throws Exception {        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();        XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream("C:\\jay.xml"));        XMLEvent event = null;        StringBuffer stringBuffer = new StringBuffer();        while (xmlEventReader.hasNext()) {            event = xmlEventReader.nextEvent();            stringBuffer.append(event.toString());        }        System.out.println("xml文档解析后果:");        System.out.println(stringBuffer);    }}

运行后果:

xml文档解析后果:<?xml version="1.0" encoding='GBK' standalone='yes'?><list>    <singer name='jay' age='8'></singer>    <singer name='eason' age='10'></singer></list>ENDDOCUMENT

6. Common Annotations

Common annotations本来是Java EE 5.0(JSR 244)标准的一部分,当初SUN把它的一部分放到了Java SE 6.0中。随着Annotation元数据性能退出到Java SE 5.0外面,很多Java 技术都会用Annotation局部代替XML文件来配置运行参数。

以下列举Common Annotations 1.0外面的几个Annotations:

  • @Generated:用于标注生成的源代码
  • @Resource: 用于标注所依赖的资源,容器据此注入内部资源依赖,有基于字段的注入和基于setter办法的注入两种形式 。
  • @Resources:同时标注多个内部依赖,容器会把所有这些内部依赖注入
  • @PostConstruct:标注当容器注入所有依赖之后运行的办法,用来进行依赖注入后的初始化工作,只有一个办法能够标注为PostConstruct 。
  • @PreDestroy:当对象实例将要被从容器当中删掉之前,要执行的回调办法要标注为PreDestroy

7. Compiler API

javac编译器能够把.java的源文件编译为.class文件,JDK 6的新个性Compiler API(JSR 199)也能够动静编译Java源文件。

public class CompilerApiTest {    public static void main(String[] args) throws Exception {        JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();        StandardJavaFileManager standardJavaFileManager = javaCompiler.getStandardFileManager(null,null,null);        Iterable<? extends JavaFileObject> javaFileObjects = standardJavaFileManager.getJavaFileObjects("C:\\Singer.java");        javaCompiler.getTask(null, standardJavaFileManager, null, null, null, javaFileObjects).call();        standardJavaFileManager.close();    }}

运行后果:会在C目录生成Singer.class文件

8. 对脚本语言的反对(如: ruby, groovy, javascript)

JDK6减少了对脚本语言的反对(JSR 223),原理是将脚本语言编译成字节码,这样脚本语言也能享受Java平台的诸多劣势,包含可移植性,平安等。JDK6实现蕴含了一个基于Mozilla Rhino的 脚本语言引擎,因而能够反对javascript,当然JDK也反对ruby等其余语言

public class JavaScriptTest {    public static void main(String[] args) throws Exception {        ScriptEngineManager factory = new ScriptEngineManager();        ScriptEngine engine = factory.getEngineByName("JavaScript");        String script;        try {            script = "print('Hello')";            engine.eval(script);// 执行脚本        }catch (Exception e) {            e.printStackTrace();        }    }}//outputHello

Java 7 新个性

1.switch 反对String字符串类型。

String singer = "jay";switch (singer) {       case "jay" :            System.out.println("周杰伦");             break;       case "eason" :            System.out.println("陈奕迅");            break ;       default :            System.out.println("其余");            break ;   }

2.try-with-resources,资源主动敞开

JDK 7 之前:

BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt"));try {   return br.readLine();} finally {   br.close();}

JDK 7 之后:

/* * 申明在try括号中的对象称为资源,在办法执行结束后会被主动敞开 */try (BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt")) {   return br.readLine();}

3. 整数类型如(byte,short,int,long)可能用二进制来示意

//0b或者0B示意二进制int a = 0b010;int b = 0B010;

4. 数字常量反对下划线

int a = 11_11;//a的值为1111,下划线不影响理论值,晋升可读性

5. 泛型实例化类型主动推断,即”<>”

JDK 7 之前:

Map<String, List<String>> map = new HashMap<String, List<String>>();

JDK 7之后:

//不须申明类型,主动依据后面<>推断其类型Map<String, List<String>> map = new HashMap<>();

6.一个catch中捕捉多个异样类型,用(|)分隔开

JDK 7之前

try{   //do something} catch (FirstException e) {     logger.error(e);} catch (SecondException e) {     logger.error(ex);}

JDk 7之后

try{   //do something} catch (FirstException | SecondException e) {     logger.error(e);}

7. 加强的文件系统

Java7 提供了全新的NIO2.0 API,不便文件治理的编码。如,能够在java.nio.file包下应用Path、Paths、Files、WatchService等罕用类型。

Path path = Paths.get("C:\\jay\\七里香.txt"); //创立Path对象byte[] bytes= Files.readAllBytes(path);  //读取文件System.out.println(path.getFileName()); //获取以后文件名称System.out.println(path.toAbsolutePath()); // 获取文件绝对路径System.out.println(new String(bytes, "utf-8"));

8. Fork/join 框架

Java7提供的一个用于并行执行工作的框架,是一个把大工作宰割成若干个小工作,最终汇总每个小工作后果后失去大工作后果的框架。

Fork/join计算1-1000累加值:

public class ForkJoinPoolTest {    private static final Integer DURATION_VALUE = 100;    static class ForkJoinSubTask extends RecursiveTask<Integer>{        // 子工作开始计算的值        private Integer startValue;        // 子工作完结计算的值        private Integer endValue;        private ForkJoinSubTask(Integer startValue , Integer endValue) {            this.startValue = startValue;            this.endValue = endValue;        }        @Override        protected Integer compute() {            //小于肯定值DURATION,才开始计算            if(endValue - startValue < DURATION_VALUE) {                System.out.println("执行子工作计算:开始值 = " + startValue + ";完结值 = " + endValue);                Integer totalValue = 0;                for (int index = this.startValue; index <= this.endValue; index++) {                    totalValue += index;                }                return totalValue;            } else {                // 将工作拆分,拆分成两个工作                ForkJoinSubTask subTask1 = new ForkJoinSubTask(startValue, (startValue + endValue) / 2);                subTask1.fork();                ForkJoinSubTask subTask2 = new ForkJoinSubTask((startValue + endValue) / 2 + 1 , endValue);                subTask2.fork();                return subTask1.join() + subTask2.join();            }        }    }    public static void main(String[] args) throws ExecutionException, InterruptedException {        // Fork/Join框架的线程池        ForkJoinPool pool = new ForkJoinPool();        ForkJoinTask<Integer> taskFuture =  pool.submit(new ForkJoinSubTask(1,1000));        Integer result = taskFuture.get();        System.out.println("累加后果是:" + result);    }}

运行后果:

...执行子工作计算:开始值 = 189;完结值 = 250执行子工作计算:开始值 = 251;完结值 = 313执行子工作计算:开始值 = 314;完结值 = 375执行子工作计算:开始值 = 376;完结值 = 438执行子工作计算:开始值 = 439;完结值 = 500执行子工作计算:开始值 = 501;完结值 = 563执行子工作计算:开始值 = 564;完结值 = 625执行子工作计算:开始值 = 626;完结值 = 688执行子工作计算:开始值 = 689;完结值 = 750执行子工作计算:开始值 = 751;完结值 = 813执行子工作计算:开始值 = 814;完结值 = 875执行子工作计算:开始值 = 876;完结值 = 938执行子工作计算:开始值 = 939;完结值 = 1000累加后果是:500500

Java 8 新个性

1.lambada表达式

Lambda 容许把函数作为一个办法的参数,传递到办法中

语法格局:

(parameters) -> expression 或 (parameters) ->{ statements; }

代码示例:

Arrays.asList("jay", "Eason", "SHE").forEach(       ( String singer ) -> System.out.print( singer + ",") );

2. 函数式接口

Lambda的设计者为了让现有的性能与Lambda表达式很好兼容,设计出函数式接口。

  • 函数式接口是指只有一个函数的接口,能够隐式转换为lambada表达式。
  • Java 8 提供了注解@FunctionalInterface,显示申明一个函数式接口。
  • java.lang.Runnable和java.util.concurrent.Callable是函数式接口的例子~
@FunctionalInterfacepublic interface Runnable {    public abstract void run();}

3. 办法援用

办法援用提供了十分有用的语法,能够间接援用已有Java类或对象(实例)的办法或结构器。它与Lambda表达式配合应用,能够缩小冗余代码,使代码更加简洁。

//利用函数式接口Consumer的accept办法实现打印,Lambda表达式如下Consumer<String> consumer = x -> System.out.println(x);consumer.accept("jay");//援用PrintStream类(也就是System.out的类型)的println办法,这就是办法援用consumer = System.out::println;consumer.accept("关注公众号捡田螺的小男孩");

4. 默认办法

默认办法就是一个在接口外面有了一个实现的办法。它容许将新办法增加到接口,但不强制实现了该接口的类必须实现新的办法。

public interface ISingerService {    // 默认办法    default void sing(){        System.out.println("唱歌");    }    void writeSong();}//JaySingerServiceImpl 不必强制实现ISingerService的默认sing()办法public class JaySingerServiceImpl implements ISingerService {    @Override    public void writeSong() {        System.out.println("写了一首七里香");    }}

5.Stream API

Stream API,反对对元素流进行函数式操作,它集成在Collections API 中,能够对汇合进行批量操作。罕用API:

  • filter 筛选
  • map流映射
  • reduce 将流中的元素组合起来
  • collect 返回汇合
  • sorted 排序
  • flatMap 流转换
  • limit返回指定流个数
  • distinct去除反复元素
public class Singer {    private String name;    private Integer songNum;    private Integer age;    ...}List<Singer> singerList = new ArrayList<Singer>();singerList.add(new Singer("jay", 11, 36));singerList.add(new Singer("eason", 8, 31));singerList.add(new Singer("JJ", 6, 29));List<String> singerNameList = singerList.stream()                .filter(singer -> singer.getAge() > 30)  //筛选年龄大于30                .sorted(Comparator.comparing(Singer::getSongNum))  //依据歌曲数量排序                .map(Singer::getName)  //提取歌手名字                .collect(Collectors.toList()); //转换为List

6. Optional

Java 8引入Optional类,用来解决NullPointerException。Optional代替if...else解决空指针问题,使代码更加简洁。

if...else 判空

Singer singer = getSingerById("666");if (singer != null) {    String name  = singer.getName();    System.out.println(name);}

Optional的判空

Optional<Singer> singer = Optional.ofNullable(getSingerById("666"));singer.ifPresent(s -> System.out.println(s.getName()));

7. Date Time API

JDK 8之前的日期API解决存在非线程平安、时区解决麻烦等问题。Java 8 在 java.time包下提供了新的日期API,简化了日期的解决~

LocalDate today = LocalDate.now();int year = today.getYear();System.out.println("往年是" + year);//是否平年System.out.println("往年是不是平年:" + today.isLeapYear());LocalDateTime todayTime = LocalDateTime.now();System.out.println("以后工夫" + todayTime);//时区指定System.out.println("美国工夫:" + ZonedDateTime.of(todayTime,ZoneId.of("America/Los_Angeles")));        LocalDate specailDate = LocalDate.of(2020, 6, 20);LocalDate expectDate = specailDate.plus(100, ChronoUnit.DAYS);System.out.println("比拟特地的一天" + specailDate);System.out.println("非凡日期的100天" + expectDate);

8. 反复注解

反复注解,即一个注解能够在一个类、属性或者办法上同时应用屡次;用@Repeatable定义反复注解

@Repeatable(ScheduleTimes.class)public @interface ScheduleTime {    String value();}public @interface ScheduleTimes {    ScheduleTime[] value();}public class ScheduleTimeTask {    @ScheduleTime("10")    @ScheduleTime("12")    public void doSomething() { }}

9. Base64

Java 8把Base64编码的反对退出到官网库中~

String str = "公众号:捡田螺的小男孩";String encoded = Base64.getEncoder().encodeToString(str.getBytes( StandardCharsets.UTF_8));String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);

10. JVM的新个性

应用元空间Metaspace代替长久代(PermGen space),JVM参数应用-XX:MetaSpaceSize和-XX:MaxMetaspaceSize设置大小。

Java 9 新个性

1. java模块零碎

什么是模块化?

一个大型零碎,比方一个商城网站,它会蕴含很多模块的,如:订单模块,用户信息模块,商品信息模块,广告位模块等等。各个模块之间会互相调用。如果每个模块独自运行都会带动其余所有模块,性能十分低效。然而,如果某一模块运行时,只会启动它所依赖的模块,性能大大晋升。这就是JDK 9模块化的思维。

什么是JDK 9模块化?

Java 平台模块零碎,即Project Jigsaw,把模块化开发实际引入到了Java平台中。在引入了模块零碎之后,JDK 被从新组织成94个模块。Java 利用能够通过新增的jlink 工具,创立出只蕴含所依赖的JDK模块的自定义运行时镜像。这样能够极大的缩小Java运行时环境的大小。

Java 9 模块的重要特色:

  • 在其工件(artifact)的根目录中蕴含了一个形容模块的 module-info.class 文 件。
  • 工件的格局能够是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。
  • 这个文件由根目录中的源代码文件 module-info.java 编译而来。
  • 该模块申明文件能够形容模块的不同特色。

在 module-info.java 文件中,咱们能够用新的关键词module来申明一个模块,如下所示。上面给出了一个模块com.mycompany.mymodule的最根本的模块申明

module com.jay.sample {   //关键词module来申明一个模块    exports com.jay.sample; //应用 exports能够申明模块对其余模块所导出的包。    requires com.jay.common; //应用requires能够申明模块对其余模块的依赖关系。}

2. 不可变汇合工厂办法

为了创立不可变汇合,JDK9之前酱紫的:

List<String> stringList = new ArrayList<>();stringList.add("关注公众号:");stringList.add("捡田螺的小男孩");List<String> unmodifiableList = Collections.unmodifiableList(stringList);

JDK 9 提供了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂办法来创立不可变汇合:

List<String> unmodifiableList = List.of("关注公众号:","捡田螺的小男孩");

3. 接口反对公有办法

JDK 8反对在接口实现默认办法和静态方法,然而不能在接口中创立公有办法,为了防止了代码冗余和进步浏览性,JDK 9在接口中反对公有办法。

public interface IPrivateInterfaceTest {    //JDK 7 之前    String a = "jay";    void method7();    //JDK 8    default void methodDefault8(){        System.out.println("JDK 8新个性默认办法");    }    static void methodStatic8() {        System.out.println("JDk 8新个性静态方法");    }        //Java 9 接口反对公有办法    private void method9(){}}

4. 钻石操作符降级

  • 钻石操作符是在 java 7 中引入的,能够让代码更易读,但它不能用于匿名的外部类。
  • 在 java 9 中, 它能够与匿名的外部类一起应用,从而进步代码的可读性。
//JDK 5,6Map<String, String> map56 = new HashMap<String,String>();//JDk 7,8Map<String, String> map78 = new HashMap<>();//JDK 9 联合匿名外部类的实现Map<String, String> map9 = new HashMap<>(){};

5. Optional 类改良

java 9 中,java.util.Optional 增加了很多新的有用办法,如:

  • stream()
  • ifPresentOrElse()
  • or()

ifPresentOrElse 办法的改良就是有了 else,承受两个参数 Consumer 和 Runnable。

import java.util.Optional; public class OptionalTest {   public static void main(String[] args) {      Optional<Integer> optional = Optional.of(1);       optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->          System.out.println("Not Present."));       optional = Optional.empty();       optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->          System.out.println("Not Present."));   }  }

6. 多版本兼容Jar包

很多公司应用的JDK都是老版本的,JDK6、JDk5 ,甚至JDk4的,不是他们不想降级JDk版本,而是放心兼容性问题。JDK 9的一个新个性,多版本兼容Jar包解决了这个问题。举个例子:假如你始终用的是小米8,曾经十分习惯它的运行流程了,忽然进去小米9,即便小米9很多新性能引人入胜,然而有些人不会轻易买小米9,因为曾经曾经习惯小米8的流程。同理,为什么很多公司不降级JDK,就是在此。然而呢,JDK 9的这个性能很弱小,它能够让你的版本升级到JDK 9,然而还是老版本的运行流程,即在老的运行流程继承新的性能~

7. JShell工具

jShell工具相当于cmd工具,而后呢,你能够像在cmd工具操作一样,间接在下面运行Java办法,Java语句等~

jshell> System.out.println("关注公众号:捡田螺的小男孩");关注公众号:捡田螺的小男孩

8. try-with-resources的改良

JDK 9对try-with-resources异样解决机制进行了降级~

//JDK 7,8try (BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt")) {   br.readLine();}catch(IOException e){  log.error("IO 异样,e:{}",e);}//JDk 9BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt")try(br){  br.readLine();}catch(IOException e){  log.error("IO 异样,e:{}",e);}

9. Stream API的改良

JDK 9 为Stream API引入以下这些办法,丰盛了流解决操作:

  • takeWhile()
  • dropWhile()
  • iterate
  • ofNullable

takeWhile

应用一个断言(Predicate 接口)作为参数,返回给定Stream的子集直到断言语句第一次返回 false

// 语法格局default Stream<T> takeWhile(Predicate<? super T> predicate)//代码示例Stream.of(1,2,3).takeWhile(s-> x<2)         .forEach(System.out::println);  //输入 1

dropWhile

与 takeWhile()作用相同,应用一个断言(Predicate 接口)作为参数,直到断言语句第一次返回true,返回给定Stream的子集

//语法default Stream<T> dropWhile(Predicate<? super T> predicate)//代码示例Stream.of(1,2,3).dropWhile(s-> x<2)         .forEach(System.out::println);//输入23

iterate

iterate() 办法可能返回以seed(第一个参数)结尾,匹配 Predicate(第二个参数)直到返回false,并应用第三个参数生成下一个元素的元素流。

//语法static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)//代码示例IntStream.iterate(2, x -> x < 10, x -> x*x).forEach(System.out::println);//输入24

ofNullable

如果指定元素为非null,则获取一个元素并生成单个元素流,元素为null则返回一个空Stream。

//语法static <T> Stream<T> ofNullable(T t)//代码示例Stream<Integer> s1= Stream.ofNullable(100);s1.forEach(System.out::println)Stream<Integer> s2 = Stream.ofNullable(null);s2.forEach(System.out::println)//输入100

10.其余

  • HTTP 2客户端 (反对 WebSocket和 HTTP2 流以及服务器推送)
  • 过程API(管制和治理操作系统过程)
  • String底层存储构造更改(char[]替换为byte[])
  • 标识符增加限度( String _ ="hello"不能用)
  • 响应式流 API (反对Java 9中的响应式编程)

Java 10 新个性

1.局部变量类型推断

JDK 10减少了局部变量类型推断(Local-Variable Type Inference)性能,让 Java 能够像Js里的var一样能够主动推断数据类型。Java中的var是一个保留类型名称,而不是关键字。

JDK 10之前

List<String> list = new ArrayList<String>();Stream<Integer> stream = Stream.of(1, 2, 3);

JDK 10 之后

var list = new ArrayList<String>(); // ArrayList<String>var stream =  Stream.of(1, 2, 3);

var 变量类型推断的应用也有局限性,仅局限于以下场景:

  • 具备初始化器的局部变量
  • 增强型for循环中的索引变量
  • 传统for循环中申明的局部变量

不能用于

  • 推断办法的参数类型
  • 结构函数参数类型推断
  • 推断办法返回类型
  • 字段类型推断
  • 捕捉表达式

2. 不可变汇合的改良

JDK 10中,List,Set,Map 提供了一个新的静态方法copyOf(Collection<? extends E> coll),它返回Collection汇合一个不可批改的正本。

JDK 源码:

static <E> List<E> copyOf(Collection<? extends E> coll) {    return ImmutableCollections.listCopy(coll);}

应用实例:

var oldList = new ArrayList<String>();oldList.add("欢送关注公众号:");oldList.add("捡田螺的小男孩");var copyList = List.copyOf(oldList);oldList.add("在看、转载、点赞三连"); copyList.add("双击666");  //UnsupportedOperationException异样

3. 并行全垃圾回收器 G1

JDK 9引入 G1 作为默认垃圾收集器,执行GC 时采纳的是基于单线程标记扫描压缩算法(mark-sweep-compact)。为了最大限度地缩小 Full GC 造成的利用进展的影响,Java 10 中将为 G1 引入多线程并行 GC,同时会应用与年老代回收和混合回收雷同的并行工作线程数量,从而缩小了 Full GC 的产生,以带来更好的性能晋升、更大的吞吐量。

4. 线程本地握手

Java 10 中线程管控引入JVM平安点的概念,将容许在不运行全局JVM平安点的状况下实现线程回调,由线程自身或者JVM线程来执行,同时放弃线程处于阻塞状态,这将会很不便使得进行单个线程或不进行线程成为可能。

5. Optional新增orElseThrow()办法

Optional、OptionalDouble等类新增一个办法orElseThrow(),在没有值时抛出异样

6. 其余新个性

  • 基于 Java 的 实验性 JIT 编译器
  • 类数据共享
  • Unicode 语言标签扩大
  • 根证书
  • 基于工夫(Time-Based)的版本控制模型

Java 11 新个性

1.字符串操作

String类是Java最罕用的类,JDK 11减少了一系列好用的字符串解决办法

  • isBlank() 判空。
  • strip() 去除首尾空格
  • stripLeading() 去除字符串首部空格
  • stripTrailing() 去除字符串尾部空格
  • lines() 宰割获取字符串流。
  • repeat() 复制字符串
// 判断字符串是否为空白"  ".isBlank();    // true// 去除首尾空格" jay ".strip();  // "jay"// 去除首部空格 " jay ".stripLeading();   // "jay "去除字符串尾部空格" jay ".stripLeading();   // " jay"// 行数统计"a\nb\nc".lines().count();    // 3// 复制字符串"jay".repeat(3);   // "jayjayjay"

2.用于 Lambda 参数的局部变量语法

局部变量类型推断是Java 10引入的新个性,然而不能在Lambda 表达式中应用。Java 11再次翻新,它容许开发者在 Lambda 表达式中应用 var 进行参数申明。

var map = new HashMap<String, Object>();map.put("公众号", "捡田螺的小男孩");map.forEach((var k, var v) -> {    System.out.println(k + ": " + v);});

3.标准化HTTP Client

Java 9 引入Http Client API,Java 10对它更新,Java 11 对它进行标准化。这几个版本后,Http Client简直被齐全重写,反对HTTP/1.1和HTTP/2 ,也反对 websockets。

HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder()            .uri(URI.create("https://github.com/whx123/JavaHome"))            .GET()            .build();// 同步HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());// 异步client.sendAsync(request, HttpResponse.BodyHandlers.ofString())    .thenApply(HttpResponse::body)    .thenAccept(System.out::println);

4. 单个命令编译运行源代码

Java 11加强了Java 启动器,使之可能运行繁多文件的Java 源代码。

  • Java 11之前,要运行一个 Java 源代码必须先编译,再运行
// 编译javac Jay.java// 运行java Jay
  • Java 11之后,只有一个java命令就搞定
java Jay.java

5. ZGC:可伸缩低提早垃圾收集器

ZGC ,即 Z Garbage Collector(垃圾收集器或垃圾回收器)。它是一个可伸缩的、低提早的垃圾收集器。
ZGC 次要为了满足如下指标进行设计:

  • GC 进展工夫不超过 10ms
  • 既能解决几百 MB 的小堆,也能解决几个 TB 的大堆
  • 利用吞吐能力不会降落超过 15%(与 G1 回收算法相比)
  • 不便在此基础上引入新的 GC 个性和利用 colord
  • 针以及 Load barriers 优化奠定根底
  • 以后只反对 Linux/x64 位平台

6.其余一些个性

  • 增加 Epsilon 垃圾收集器。
  • 反对 TLS 1.3 协定
  • 航行记录器剖析工具
  • 动静类文件常量
  • 低开销的 Heap Profiling

Java 12 新个性

1. Switch 表达式扩大(预览性能)

传统的switch语句,容易漏写break而出错,同时写法并不简洁优雅。

Java 12之前

switch (day) {    case MONDAY:    case FRIDAY:    case SUNDAY:        System.out.println(6);        break;    case TUESDAY:        System.out.println(7);        break;    case THURSDAY:    case SATURDAY:        System.out.println(8);        break;    case WEDNESDAY:        System.out.println(9);        break;}

JDk 12 之后,Switch表达式失去加强,能承受语句和表达式。

switch (day) {    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);    case TUESDAY                -> System.out.println(7);    case THURSDAY, SATURDAY     -> System.out.println(8);    case WEDNESDAY              -> System.out.println(9);}

2. 紧凑的数据格式

JDK 12 新增了NumberFormat对简单数字的格式化

NumberFormat numberFormat = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT);System.out.println(numberFormat.format(100000));//output10万

3. 字符串反对transform、indent操作

  • transform 字符串转换,能够配合函数式接口Function一起应用
List<String> list1 = List.of("jay", " 捡田螺的小男孩");List<String> list2 = new ArrayList<>();list1.forEach(element ->            list2.add(element.transform(String::strip)                    .transform((e) -> "Hello," + e))    );list2.forEach(System.out::println);//输入Hello,jayHello,捡田螺的小男孩
  • indent 缩进,每行结尾减少空格space和移除空格
String result = "Java\n Python\nC".indent(3);System.out.println(result);//输入   Java    Python   C

4. Files.mismatch(Path, Path)

Java 12 新增了mismatch办法,此办法返回第一个不匹配的地位,如果没有不匹配,则返回 -1L。

public static long mismatch(Path path, Path path2) throws IOException;

代码示例:

Path file1 = Paths.get("c:\\jay.txt");Path file2 = Paths.get("c:\\捡田螺的小男孩.txt");try { long fileMismatch = Files.mismatch(file1, file2); System.out.println(fileMismatch);} catch (IOException e) {    e.printStackTrace();}

5. Teeing Collector

Teeing Collector 是 Streams API 中引入的新的收集器实用程序,它的作用是 merge 两个 collector 的后果,API格局如下:

public static <T, R1, R2, R>    Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,    Collector<? super T, ?, R2> downstream2,    BiFunction<? super R1, ? super R2, R> merger)

间接看代码例子吧,如下为求学生的平均分和总分的例子

  List<Student> studentList= Arrays.asList(                new Student("jay", 90),                new Student("捡田螺的小男孩", 100),                new Student("捡表情的小男孩", 80)        );        String teeingResult=studentList.stream().collect(                Collectors.teeing(                        Collectors.averagingInt(Student::getScore),                        Collectors.summingInt(Student::getScore),                        (s1,s2)-> s1+ ":"+ s2                )        ); System.out.println(teeingResult); //90:270

6.其余个性

  • 反对unicode 11(684个新字符、11个新blocks、7个新脚本)
  • JVM 常量 API (次要在新的java.lang.invoke.constant包中定义了一系列基于值的符号援用类型,可能形容每种可加载常量。)
  • Shenandoah GC(低暂停工夫垃圾收集器)
  • G1 收集器晋升 (可停止的混合收集汇合、及时返回未应用的已分配内存)
  • 默认CDS档案
  • JMH 基准测试

Java 13 新个性

Switch 表达式扩大(引入 yield 关键字)

传统的switch:

private static String getText(int number) {    String result = "";    switch (number) {        case 1, 2:        result = "one or two";        break;        case 3:        result = "three";        break;        case 4, 5, 6:        result = "four or five or six";        break;        default:        result = "unknown";        break;

Java 13之后,value break 语句不再被编译,而是用 yield 来进行值返回

private static String getText(int number) {    return switch (number) {        case 1, 2:            yield "one or two";        case 3:            yield "three";        case 4, 5, 6:            yield "four or five or six";        default:            yield "unknown";    };}

2.文本块降级

Java 13之前,字符串不可能多行应用,须要通过换行本义或者换行连接符等等,反正就是好麻烦、好难保护。

String html = "<html>\n" +              "    <body>\n" +              "        <p>Hello, 捡田螺的小男孩</p>\n" +              "    </body>\n" +              "</html>\n";

Java 13之后,清新多了~

String html = """                <html>                    <body>                        <p>Hello,  捡田螺的小男孩</p>                    </body>                </html>                """;

3. SocketAPI 重构

  • 传统的Java Socket API(java.net.ServerSocket 和 java.net.Socket)依赖于SocketImpl 的外部实现
  • 在 Java 13之前,通过应用 PlainSocketImpl 作为 SocketImpl 的具体实现。
  • Java 13 中的新底层实现,引入 NioSocketImpl 的实现用以替换 SocketImpl 的 PlainSocketImpl 实现,此实现与 NIO(新 I/O)实现共享雷同的外部根底构造,并且与现有的缓冲区高速缓存机制集成在一起。

一个Socket简略例子:

import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class SocketAPITest {    public static void main(String[] args) {        try (ServerSocket serverSocket = new ServerSocket(8080)){            boolean runFlag = true;            while(runFlag){                Socket clientSocket = serverSocket.accept();                //搞事件            }        } catch (IOException e) {            e.printStackTrace();        }    }}

运行以上的实例,看下是否有以下关键词输入~

[class,load] sun.nio.ch.NioSocketImpl

4.FileSystems.newFileSystem新办法

FileSystems 类中增加了以下三种新办法,以便更容易地应用将文件内容视为文件系统的文件系统提供程序:

  • 1、newFileSystem(Path)
  • 2、newFileSystem(Path, Map<String, ?>)
  • 3、newFileSystem(Path, Map<String, ?>, ClassLoader)

5. 加强 ZGC 开释未应用内存

  • ZGC 是Java 11 中引入的最为注目的垃圾回收个性,是一种可伸缩、低提早的垃圾收集器。然而理论应用中,它不可能被动将未应用的内存开释给操作系统。
  • Java 13 中对 ZGC 的改良,包含开释未应用内存给操作系统、反对最大堆大小为 16TB、JVM参数-XX:SoftMaxHeapSize 来软限度堆大小

6.其余个性

  • 动静 CDS 存档, 扩大了 Java 10 中引入的类数据共享性能, 应用CDS 存档变得更容易。
  • 文本块的字符串类新办法,如formatted(Object…args),stripIndent()等。

Java 14 新个性

1. instanceof模式匹配

instanceof 传统应用形式:

if (person instanceof Singer) {    Singer singer = (Singer) person;    singer.sing();} else if (person instanceof Writer) {    Writer writer = (Writer) person;    writer.write();}

Java 14 对 instanceof 进行模式匹配改良之后

if (person instanceof Singer singer) {    singer.sing();} else if (person instanceof Writer writer) {   writer.write();}

2.Record 类型(预览性能)

Java 14将Record 类型作为预览个性而引入,有点相似于Lombok 的@Data注解,看个例子吧:

public record Person(String name, int age) {    public static String address;    public String getName() {        return name;    }}

反编译后果:

public final class Person extends java.lang.Record {    private final java.lang.String name;    private final java.lang.String age;    public Person(java.lang.String name, java.lang.String age) { /* compiled code */ }    public java.lang.String getName() { /* compiled code */ }    public java.lang.String toString() { /* compiled code */ }    public final int hashCode() { /* compiled code */ }    public final boolean equals(java.lang.Object o) { /* compiled code */ }    public java.lang.String name() { /* compiled code */ }    public java.lang.String age() { /* compiled code */ }}

能够发现,当用 Record 来申明一个类时,该类将主动领有上面特色:

  • 构造方法
  • hashCode() 办法
  • euqals() 办法
  • toString() 办法
  • 类对象被final 关键字润饰,不能被继承。

3. Switch 表达式-标准化

switch 表达式在之前的 Java 12 和 Java 13 中都是处于预览阶段,终于在 Java 14 标准化,成为稳固版本。

  • Java 12 为switch 表达式引入Lambda 语法
  • Java 13 应用yield代替 break 关键字来返回表达式的返回值。
String result = switch (day) {    case "M", "W", "F" -> "MWF";    case "T", "TH", "S" -> "TTS";    default -> {        if (day.isEmpty()) {            yield "Please insert a valid day.";        } else {            yield "Looks like a Sunday.";        }    }};System.out.println(result);

4. 改良 NullPointerExceptions提示信息

Java 14 之前:

String name = song.getSinger().getSingerName() //堆栈信息Exception in thread "main" java.lang.NullPointerException    at NullPointerExample.main(NullPointerTest.java:6)

Java 14,通过引入JVM 参数-XX:+ShowCodeDetailsInExceptionMessages,能够在空指针异样中获取更为具体的调用信息。

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Singer.getSingerName()" because the return value of "rainRow.getSinger()" is null    at NullPointerExample.main(NullPointerTest.java:6)

5. 其余个性

  • G1 的 NUMA 可辨认内存调配
  • 删除 CMS 垃圾回收器
  • GC 反对 MacOS 和 Windows 零碎

Java 15 新个性


1.EdDSA 数字签名算法

  • 应用 Edwards-Curve 数字签名算法(EdDSA)实现加密签名。
  • 与其它签名计划相比,EdDSA 具备更高的安全性和性能。
  • 失去许多其它加密库(如 OpenSSL、BoringSSL)的反对。

2.Sealed Classes(关闭类,预览)

关闭类,能够是关闭类、关闭接口,避免其余类或接口扩大或实现它们。

public abstract sealed class Singer    permits Jay, Eason{    ...}

类Singer被sealed 润饰,是关闭类,只能被2个指定子类(Jay, Eason)继承。

3. Hidden Classes(暗藏类)

  • 暗藏类天生为框架设计的。
  • 暗藏类只能通过反射拜访,不能间接被其余类的字节码。

4. Remove the Nashorn JavaScript Engine

  • Nashorn太难保护了,移除 Nashorn JavaScript引擎成为一种必然
  • 其实早在JDK 11 中就曾经被标记为 deprecated 了。

5.Reimplement the Legacy DatagramSocket API(从新实现DatagramSocket API)

  • 从新实现老的DatagramSocket API
  • 更改java.net.DatagramSocket 和 java.net.MulticastSocket 为更加简略、现代化的底层实现。

6.其余

  • Disable and Deprecate Biased Locking(筹备禁用偏差锁)
  • instanceof 主动匹配模式(预览)
  • ZGC,一个可伸缩、低提早的垃圾回收器。(转正)
  • Text Blocks,文本性能转正(JDK 13和14预览,14终于转正)
  • Remove the Solaris and SPARC Ports(删除 Solaris 和 SPARC 端口)
  • 内部存储器拜访 API(容许Java 应用程序平安无效地拜访 Java 堆之外的内部内存。)
  • Record类型二次预览(在Java 14就预览过啦)

参考与感激

  • JDK6 新个性
  • Java 7的新性能
  • Java 9 新个性概述
  • Java 9 新个性
  • Java 10 新个性介绍
  • Java 11 新个性介绍
  • Java 13 新个性概述
  • Java 14 新个性概述
  • JDK/Java 15公布
  • [Java 15 正式公布, 14 个新个性,刷新你的认知!!

](https://www.cnblogs.com/javas...

集体公众号