java 8发行版是自2004年发行的java 5以来最具有革命性的一个版本。java 8为java语言、编译器、类库、开发工具与jvm等带来了大量新特性。
本文为大家详细介绍了java 1.8中的几个新特性,希望能够帮助到大家。
1、lambda表达式
格式:(参数) -> {代码段}
如:new thread(() -> {system.out.println(hello world!)}).start(); 这就是lambda表达式。
lambda的实现需要依赖函数式接口,lambda本质上是匿名内部类,jdk1.8以前,如果方法内需要操作其他接口的实现方法,可以通过匿名内部类来实现,
jdk1.8之后可以通过lambda表达式来代替匿名内部类,并且更为简化。
package java8; public class lambdademo { public static void main(string[] args) { //jdk1.8之前使用接口,采用匿名内部类的方式 myinterface mi = new myinterface() { @override public void test() { system.out.println("test"); } }; mi.test(); //jdk1.8之后,使用lambda表达式 myinterface lmi = () -> { system.out.println("test"); }; lmi.test(); }}//定义一个函数式接口,只有一个抽象方法 interface myinterface{ void test();}
函数式接口 : 有且只有一个的抽象方法的接口称为函数式接口
函数式接口的常用接口 function, predicate,supplier,consumer 都在java.util.function包下
function接口:r apply(t t) 接收一个参数并返回一个对象
package java8; import java.util.function.function; public class lambdademo { public static void main(string[] args) { // function的使用 // 传统模式,第一个泛型:接收的参数类型 第二个泛型,返回的参数类型 function<string, string> function1 = new function<string, string>() { @override public string apply(string t) { return t; } }; // 调用apply方法,并获取返回结果 string res1 = function1.apply("function的使用"); system.out.println(res1); // lambda的使用,当参数只有一个且不写参数类型时,"()"可以省略 function<string, string> function2 = t -> { return t; }; // 调用apply方法,并获取返回结果 string res2 = function2.apply("function的使用"); system.out.println(res2); }}
predicate接口 : boolean test(t t) 接收一个参数,返回一个boolean值
常用来比较
package java8; import java.util.function.*; public class lambdademo { public static void main(string[] args) { // predicate的使用 // 传统模式,泛型参数:接收的参数类型 predicate<integer> predicate1 = new predicate<integer>() { @override public boolean test(integer t) { // 大于等于10就为真,否则为假 return t >= 10; } }; // 执行predicate1的方法 system.out.println(predicate1.test(11)); system.out.println(predicate1.test(8)); //使用lambda表达式 predicate<integer> predicate2 = new predicate<integer>() { @override public boolean test(integer t) { // 大于等于10就为真,否则为假 return t >= 10; } }; // 执行predicate1的方法 system.out.println(predicate2.test(11)); system.out.println(predicate2.test(8)); }}
supplier接口 :t get() 返回一个对象
生产者消费者模式的生产者,只管生产对象
package java8; import java.util.function.*; public class lambdademo { public static void main(string[] args) { //supplier的使用 // 传统模式,泛型参数:返回的参数类型 supplier<string> s1 = new supplier<string>() { @override public string get() { return new string("supplier"); } }; //调用 system.out.println(s1.get()); // 使用lambda表达式 //当代码只有一句时,可以省略"{}",不接收参数时,"()"不能省略 supplier<string> s2 = () -> new string("supplier"); system.out.println(s2.get()); }}
consumer接口 : accept(t t)接收一个参数,不返回任何值
生产者消费者模式的生产者,只管消费对象
package java8; import java.util.function.*; public class lambdademo { public static void main(string[] args) { // consumer的使用 // 传统模式,泛型参数:返回的参数类型 consumer<string> con1 = new consumer<string>() { @override public void accept(string t) { system.out.println(t); } }; con1.accept("consumer"); //使用lambda表达式,同时省略"()","{}" consumer<string> con2 = t -> system.out.println(t); con2.accept("consumer"); }}
(学习视频分享:java视频教程)
lambda实战用法:
package java8; import java.util.function.*; public class lambdademo { public static void main(string[] args) { //runnable的实现, new thread(() -> { system.out.println(thread.currentthread().getname() + " run"); }).start(); system.out.println(thread.currentthread().getname() + " run"); }}
2、方法引用:
方法引用是指lambda表达式中只有一句方法调用,而这个方法有真实存在,此时就可以用方法引用来替换lambda表达式。
方法引用有四种类型
类名::静态方法名
对象名::实例方法名
类名::实例方法名
类名::new
package java8; import java.util.arrays;import java.util.collections;import java.util.list;import java.util.function.biconsumer;import java.util.function.supplier; public class methodreferencedemo { public static void main(string[] args) { // 定义3个student对象 student s1 = new student("zhangsan", 90); student s2 = new student("lisi", 60); student s3 = new student("wangwu", 70); // 添加到集合 list<student> students = arrays.aslist(s1, s2, s3); //普通的lambda实现 // sort接收两个参数,第一个参数,要排序的集合,第二个参数,comparator接口的实现 // collections.sort(students, (stu1,stu2) -> studentsortutil.sortbyscore(stu1,stu2)); // students.foreach(t -> system.out.println(t.getscore())); // 方法引用1---类名::静态方法名 // collections.sort(students, studentsortutil::sortbyscore); // students.foreach(t -> system.out.println(t.getscore())); //创建实例对象,调用实例对象的方法 studentsortutil ssu = new studentsortutil(); //普通的lambda实现// collections.sort(students, (stu1, stu2) -> ssu.sortbyscoreinstance(stu1, stu2));// students.foreach(t -> system.out.println(t.getscore())); // 方法引用2---对象名::实例方法名// collections.sort(students, ssu::sortbyscoreinstance);// students.foreach(t -> system.out.println(t.getscore())); /* * 方法引用3---类名::实例方法名 * student的sortbyscore()只有一个参数,而comparator的实现需要两个参数,为什么编译器不报错? * 这是因为sortbyscore是一个普通方法,要使用这个方法肯定要有一个student类的实例对象来调用 * 而调用的这个方法的对象就作为comparator的第一个参数对象传递进来 * 例string的compareto()方法,调用这个方法首先要有一个string的实例对象, * 此处str就是这个实例对象,str就作为comparator的第一个参数 * "hello"这个string对象就作为第二个参数 * string str = new string("str1"); * str.compareto("hello"); */ collections.sort(students, student::sortbyscore); //创建一个新的student对象,使用lambda表达式创建 //不接收参数,返回一个对象,其实就是supplier接口的实例 supplier<student> su1 = () -> new student(); //方法引用4---类名::new supplier<student> su2 = student::new; //biconsumer是consumer的扩展,可以接受两个参数返回一个值 biconsumer<string, integer> bc1 = (name,score) -> new student(name,score); //替换上面的lambda表达式,需要接收两个参数,所以调用的是有参构造方法 biconsumer<string, integer> bc2 = student::new; }} //定义一个学生实体类class student { private string name; private int score; public student() { } public student(string name, int score) { this.name = name; this.score = score; } public string getname() { return name; } public void setname(string name) { this.name = name; } public int getscore() { return score; } public void setscore(int score) { this.score = score; } public int sortbyscore(student stu) { return this.getscore() - stu.getscore(); } public int sortbyname(student stu) { return this.getname().compareto(stu.getname()); }} //定义一个学生排序工具类class studentsortutil { public static int sortbyscore(student stu1, student stu2) { return stu1.getscore() - stu2.getscore(); } public static int sortbyname(student stu1, student stu2) { return stu1.getname().compareto(stu2.getname()); } // 普通方法,创建对象才能调用 public int sortbyscoreinstance(student stu1, student stu2) { return stu1.getscore() - stu2.getscore(); } // 普通方法,创建对象才能调用 public int sortbynameinstance(student stu1, student stu2) { return stu1.getname().compareto(stu2.getname()); }}
3、stream:
stream分为中间操作和终止操作,中间操作会继续返回一个新的流,终止操作返回一个结果。
一行代码中如果只有中间操作,则不会执行,只有遇见终止操作才会执行。
package java8; import java.util.arraylist;import java.util.arrays;import java.util.linkedlist;import java.util.stream.stream; public class streamdemo { public static void main(string[] args) { //stream的使用 //创建流,参数为可变参数 stream<integer> stream = stream.of(50,66,88); //将stream转化为数组 //object[] array = stream.toarray(); //system.out.println(arrays.tostring(array)); //筛选过滤条件,参数为predicate,动作自己指定,找到大于60的数 //流分为中间操作和终止操作,节点流会继续返回一个流对象,终止操作会返回一个结果, //只有中间流,代码不会执行,只有遇见终止操作才会执行 //stream.filter((target) -> target > 60).foreach(system.out::println); //map对数据进行操作,接收一个function实例 例:对流中的每个元素都乘以2 stream.map((t) -> 2 * t).foreach(system.out::println); //流的无限模式,会对seed一直执行unaryoperator的事件,一般和limit配合使用 //skip(n)跳过n个元素,limit(n) 返回n个元素的流 stream.iterate(0, t -> t + 2).skip(2).limit(6).foreach(system.out::println); //将流转换为集合对象,第一个参数,传递一个supplier 最终结果类型由此提供 //第二个参数 biconsumer() 传递两个参数,第一个要操作的集合,第二个当前的流元素 //第三个元素biconsumer() 传递两个集合,最终合并成一个集合 //类似stringbuffer.append()方法// stream.collect(() -> new arraylist<integer>(),// (target,item)-> target.add(item),// (result,target)-> result.addall(target)).foreach(system.out::println); //可以使用方法引用简化 stream.collect(linkedlist::new,linkedlist::add,linkedlist::addall); }}
相关推荐:java入门教程
以上就是初步学习java 1.8新特性的详细内容。