Java8新特性学习总结

来源:互联网 发布:淘宝店铺首页全屏轮播 编辑:程序博客网 时间:2024/05/16 09:40

Java8新特性学习总结

前言

最近深入研究了Java8的新特性,感觉Java8的这些新特性对Java编程的影响还是很大的,尤其是新的Lambda表达式,方法与构造函数引用,Stream API,新的Date/Time API,以及Java8对并行编程的扩展,都让人耳目一新。其实这些新的特性在其它现代化的编程语言中早已出现,比如C#等,不过Java8引用了这些新的特性,能让Java的代码看起来更优雅、更高效,更符合现代语言的编程风格,也着实让人兴奋。

目录

1.    函数式接口@FunctionalInterface

2.    接口的默认方法和静态方法

3.    方法和构造函数引用

4.    Lambda表达式

5.    StreamsAPI

6.    并行数组

7.    新的Date/Time API

8.    注解的新特性—重复注解和扩展注解

9.    Base64类的标准化

10. 新的JavaScript脚本引擎Nashorn

11. 新的类型分析器jdeps命令

12. Java编译器的新特性-parameters编译参数的支持

正文

1.   函数式接口@FunctionalInterface

函数式接口是只有一个抽象函数的接口,但是接口里面可以有默认方法和静态方法。函数式接口可以使用@FunctionalInterface注解来标明。 Lambda表达式的核心就是函数式接口和方法引用,每一个Lambda表达式其实都是对函数式接口的抽象函数的引用,示例如下:

@FunctionalInterface
public interface IConverter{
   
/**
     *
把内容为数字的字符串转换成数字
    
* @param value
    
* @return
    
*/
   
int convert(String value);

   
/**
     *
接口的默认方法示例
    
* @param str
    
*/
   
default void test(String str){
        System.
out.println("hello"+ str);
   
}

   
/**
     *
接口的静态方法示例
    
* @param str
    
*/
   
static void test2(String str){
        System.
out.println("hello"+ str);
   
}

}

一个简单的Lambda表达式示例如下:

List<String> list=newArrayList<>();
list.add("item3");
list.add("item1");
list.add("item2");
//传统写法
list.sort(newComparator<String>(){
   
@Override
   
public int compare(String str1,String str2) {
       
return str1.compareTo(str2);
   
}
})
;

//Lambda表达式写法
list.sort((str1,str2)->{
    
return str1.compareTo(str2);
});

2.   接口的默认方法和静态方法

从Java8开始,接口提供了对默认方法和静态方法的支持,通过default关键字修饰的方法就是默认方法,示例如下:

@FunctionalInterface
public interface IConverter{
   
/**
     *
把内容为数字的字符串转换成数字
    
* @param value
    
* @return
    
*/
   
int convert(String value);

   
/**
     *
接口的默认方法示例
    
* @param str
    
*/
   
default void test(String str){
        System.
out.println("hello"+ str);
   
}

   
/**
     *
接口的静态方法示例
    
* @param str
    
*/
   
static void test2(String str){
        System.
out.println("hello"+ str);
   
}

}

3.   方法和构造函数引用

方法引用的核心是类的函数声明和只有一个抽象函数的接口的函数的声明一致即可,详情参照下面的示例:

@FunctionalInterface
public interface Supplier<T> {

   
/**
     * Gets a result.
     *
     * @return a result
     */
   
T get();
}

@FunctionalInterface
public interface Consumer<T> {

   
/**
     * Performs this operation on thegiven argument.
     *
     * @param
t the inputargument
     */
   
void accept(Tt);
}


public class Person {
   
private Stringname="kgdwbb";
    public
Person(){

    }

   
public Person(String name){
       
this.name=name;
   
}

   
public staticvoid sayHello(){
        System.
out.println("Helloboy");
   
}

   
public staticvoid saySomething(String content){
        System.
out.println("Personsaid: "+content);
   
}

   
public void showName(){
        System.
out.println("my name is"+name);
   
}

   
public void showNewName(StringnewName){
        System.
out.println("my newname is "+newName);
   
}

   
public void showInfo(String name,String gender,intage){
        System.
out.println("name ="+name+" , gender = "+gender+" , age ="+age);
   
}
}

l  构造函数引用,示例如下:

Supplier<Person> supplier=Person::new;
supplier.get().showName();

静态方法引用,示例如下:

//无参静态方法引用
Runnable runnable=Person::sayHello;
new
Thread(runnable).start();

new
Thread(Person::sayHello).start();

//有参静态方法引用
Consumer<String> consumer=Person::saySomething;
consumer.accept("hello boy");

 

非静态方法引用,示例如下:

Person person=newPerson("wubb");
Consumer<String> consumer=person::showNewName;
consumer.accept("xiaobei");

4.   Lambda表达式

Lambda表达式的核心就是函数式接口和方法引用,Lambda表达式的格式示例:

多行Lambda表达式格式:(参数1,参数2)->{}

单行Lambda表达式格式:无参数版:()->函数体,有参数版:(参数1,参数2)->函数体,其中函数体部分只有一行代码,如果接口函数需要返回值,在函数体里面也不用写return语句,编译器会默认生成对应的return语句

 

Lambda表达式示例:

List<String> list =new ArrayList<>();
list.add("item3");
list.add("item1");
list.add("item2");
//传统写法
list.sort(newComparator<String>(){
   
@Override
   
public int compare(String str1,String str2) {
       
return str1.compareTo(str2);
   
}
})
;

//带参数带返回值的Lambda表达式写法
list.sort((str1,str2) -> {
   
return str1.compareTo(str2);
});

//不带参数不带返回值的Lambda表达式写法
new Thread(() -> {
    System.
out.println(Thread.currentThread().getName());
}).start();

//单行Lambda表达式写法
IConverter converter = (strNum) ->Integer.valueOf(strNum);

5.   Streams API

Java8扩展了集合类,可以通过 Collection.stream() 或者Collection.parallelStream() 来创建一个Stream,前者是在单核CPU上执行,后者是在多核CPU上并发执行,在集合的数据量比较大的情况下,Collection.parallelStream()的速度更快,但是在集合的数据量不大的情况下,建议使用Collection.stream()的方式来操作集合,这样速度会比Collection.parallelStream()更快,因为省去了多核CPU的调度时间。

常用的Stream函数

List<String> list=newArrayList<>();
list.add("item3");
list.add("item1");
list.add("item2");
list.add("item1");

filter过滤函数,用来对集合中的元素进行过滤,示例代码如下:

String item= list.stream().filter((item)->item.indexOf("item2")>=0).findFirst().get();

sorted排序函数,用来对集合中的元素进行排序,示例代码如下:

list.stream().sorted().forEach((item)->{
    System.
out.println(item);
});

forEach函数,用来对集合中的元素进行迭代遍历,示例代码如下:

list.stream().sorted().forEach((item)->{    System.out.println(item);});

map函数,用来对集合中的元素进行映射,示例代码如下:

int max=list.stream().map((item)->{
    String num=item.replace(
"item","");
    return
Integer.valueOf(num);
}).max(Comparator.naturalOrder()).get();

distinct函数,用来对去除集合中的重复元素,示例代码如下:

list.stream().distinct().forEach((item)->{
    System.
out.println(item);
});

collect函数,用来对集合中的元素进行可变缩减,示例代码如下:

String str= list.stream().collect(Collectors.joining(","));

reduce函数,用来对集合中的元素进行缩减,示例代码如下:

String str= list.stream().reduce((item1,item2)->item1+","+item2).get();

常用的parallelStream 函数

parallelStream函数和 stream函数是一样的,唯一的区别如下:

list.parallelStream().forEach((item)->
{
    System.
out.println(item);
});

list.stream().forEach((item)->
{
    System.
out.println(item);
});

6.   并行数组

Java8对Arrays类进行了扩充,添加了几个利用多核CPU对数组进行并行操作的方法,比如parallelSort,parallelSetAll,parallelPrefix等。

示例代码如下:

final intarraySize=1000000;
int
[]array=new int[arraySize];
Arrays.parallelSetAll(array,(num)->ThreadLocalRandom.current().nextInt(arraySize));
Arrays.parallelSort(array);

7.   新的Date/Time API

Java8添加一个运行新的Date/Time API的包java.time包,里面有最新的Date/Time API支持类,比如Clock,Instant,LocalDate,LocalTime,LocalDateTime类

Clock代表时钟,示例代码如下:

Clock clock=Clock.systemUTC();
long
ms=clock.millis();
Instant instant=clock.instant();
long
second=instant.getEpochSecond();

LocalDate代表本地时日期,示例代码如下:

LocalDate localDate=LocalDate.parse("2017-04-23");
localDate=LocalDate.of(2017,4,23);
localDate=LocalDate.now();
localDate.plusDays(1);
localDate.minusDays(1);                                                                                                       

LocalTime代表本地时间:示例代码如下:

LocalTime localTime=LocalTime.parse("12:10:30");
localTime=LocalTime.of(12,10,30);
localTime=LocalTime.now();
localTime.plusHours(1);
localTime.minusHours(1);

LocalDateTime代表本地时期和时间,示例代码如下:

LocalDateTimelocalDateTime=LocalDateTime.parse("2017-04-23T12:10:30");
localDateTime=LocalDateTime.of(2017,4,23,12,10,30);
localDateTime=localDateTime.plusYears(1).plusMonths(1).plusDays(1).plusHours(1).plusMinutes(1).plusSeconds(1);
localDateTime=localDateTime.minusYears(1).minusMonths(1).minusDays(1).minusHours(1).minusMinutes(1).minusSeconds(1);

8.   注解的新特性—重复注解和扩展注解

重复注解

Java8允许我们把同一个类型的注解使用多次,只需要给该注解标注一下@Repeatable即可

@interfaceHints {
   
Hint[] value();
}
@Repeatable(
Hints.class)
@
interface Hint{
    String
value();
}

使用包装类当容器来存多个注解(老方法),示例代码如下:

@Hints({@Hint("hint1"),@Hint("hint2")})
class Person {}

使用多重注解(新方法),示例代码如下:

@Hint("hint1")
@Hint(
"hint2")
class Person {}

扩展注解

Java 8扩展了注解的上下文。现在几乎可以为任何东西添加注解:局部变量、泛型类、父类与接口的实现,就连方法的异常也能添加注解。示例代码如下:

public classAnnotations {
    @Retention( RetentionPolicy.RUNTIME )
    @Target( { ElementType.TYPE_USE
, ElementType.TYPE_PARAMETER} )
   
public @interfaceNonEmpty {
    }

   
public staticclass Holder<@NonEmpty T> extends @NonEmpty Object {
       
public void method()throws @NonEmptyException {
        }
    }

    
@SuppressWarnings("unused")
   
public staticvoid main(String[] args) {
       
final Holder<String > holder =new @NonEmptyHolder<String >();
       
@NonEmpty Collection<@NonEmpty String >strings =new ArrayList<>();
   
}
}

9.   Base64类的标准化

在Java 8中,Base64编码已经成为Java类库的标准。Base64类同时还提供了对URL、MIME友好的编码器与解码器(Base64.getUrlEncoder() / Base64.getUrlDecoder(), Base64.getMimeEncoder()/ Base64.getMimeDecoder())

示例代码如下:

String txt="kgdwbb";
String strBase64= Base64.getEncoder().encodeToString(txt.getBytes("utf-8"));
byte
[]data=Base64.getDecoder().decode(strBase64);
String original=newString(data,"utf-8");

10.新的JavaScript脚本引擎Nashorn

在Java8中,默认的JavaScript引擎是Nashorn,示例代码如下:

ScriptEngineManager scriptEngineManager=newScriptEngineManager();
ScriptEngine scriptEngine=scriptEngineManager.getEngineByName("nashorn");
String result= scriptEngine.eval("function add(a,b){return a+b};add(2,3);").toString();

 

同时Java8还添加了一个基于Nashorn引擎的jjs命令,用来通过命令行执行JS脚本,示例如下:

jjs hello.js

11.新的类型分析器jdeps命令

jdeps是一个很有用的命令行工具。它可以显示Java类的包级别或类级别的依赖。它接受一个.class文件,一个目录,或者一个jar文件作为输入。jdeps默认把结果输出到系统输出(控制台)上。示例如下:

jdeps zipfs.jar

12.Java编译器的新特性-parameters编译参数的支持

在Java8中,使用-parameters编译参数,可以把函数的参数名编译到java字节码中,Java8以前,Java编译器不支持这个参数,函数的名字就不能编译到java字节码中。

结尾

Java8的这些激动人心的特性将极大的影响java语言的发展,期待Java9,Java10等将会有更多令人兴奋的新特性。

 

最后,感谢大家阅读这篇文章,如果感觉哪里有不足或错误的地方,欢迎随时与我联系,我的QQ:624556373

参考资料

http://www.importnew.com/11908.html

http://www.jb51.net/article/48304.htm

http://www.open-open.com/lib/view/open1452343407151.html

 

0 0
原创粉丝点击