Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
新特性
Java8 新增了非常多的特性,我们主要讨论以下几个:
-
Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
-
方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
-
默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。
-
新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
-
Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
-
Date Time API − 加强对日期与时间的处理。
-
Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
-
Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
Java Lambda Expressions
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
Java lambda expression is treated as a function, so compiler does not create .class file.
为什么使用lambda表达式?
1. 提供函数接口的实现;
2. 更少的代码;
语法:
(argument-list) -> {body}
1) Argument-list: It can be empty or non-empty as well. (非空和空都可以)
2) Arrow-token: It is used to link arguments-list and body of expression.
3) Body: It contains expressions and statements for lambda expression. (包含表达式和语句)
无参数的语法:
() -> {
//Body of no parameter lambda
}
单个参数的语法:
(p1) -> {
//Body of single parameter lambda
}
两个参数:
(p1,p2) -> {
//Body of multiple parameter lambda
}
不使用lambda表达式:
package com.allen.java8;
interface Drawable{
public void draw();
}
public class LambdaExpressionExample {
public static void main(String[] args) {
int width = 10;
//without lambda, Drawable implementation using anonymous class
Drawable d = new Drawable(){
public void draw(){
System.out.println("Drawing "+width);}
};
d.draw();
}
}
使用lambda表达式:
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 9:54
* @Description :
*/
interface Drawble {
public void draw();
}
public class LambdaExpressionExample2 {
public static void main(String[] args) {
int width = 10;
Drawble d2 = () -> {
System.out.println("Drawing "+width);
};
d2.draw();
}
}
无参数:
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 9:59
* @Description :
*/
interface Sayale {
public String say();
}
public class LambdaExpressionExample3 {
public static void main(String[] args) {
Sayale s = () -> {
return "hello";
};
System.out.println(s.say());
}
}
单个参数:
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 10:04
* @Description :
*/
interface Sayable{
public String say(String name);
}
public class LambdaExpressionExample4 {
public static void main(String[] args) {
Sayable s1 = (name) -> {
return "Hello, "+ name;
};
System.out.println(s1.say("Sonoo"));
Sayable s2 = name -> {
return "Hello, " +name;
};
System.out.println(s2.say("Sonoo"));
}
}
多个参数:
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 10:21
* @Description :
*/
interface Addable {
int add(int a, int b);
}
public class LambdaExpressionExample5 {
public static void main(String[] args) {
Addable addable1 = (a, b) -> (a + b);
System.out.println(addable1.add(10, 20));
Addable ad2 = (int a, int b) -> (a + b);
System.out.println(ad2.add(100, 200));
}
}
返回值的问题:
In Java lambda expression, if there is only one statement, you may or may not use return keyword. You must use return keyword when lambda expression contains multiple statements.
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 10:28
* @Description :
*/
interface Addable1 {
int add(int a, int b);
}
public class LambdaExpressionExample6 {
public static void main(String[] args) {
// Lambda expression without return keyword.
Addable1 ad1 = (a, b) -> (a + b);
System.out.println(ad1.add(10, 20));
// Lambda expression with return keyword.
Addable1 ad2 = (int a, int b) -> {
return (a + b);
};
System.out.println(ad2.add(100,200));
}
}
foreach循环:
package com.allen.java8;
import java.util.ArrayList;
import java.util.List;
/**
* @author :jhys
* @date :Created in 2021/7/20 10:42
* @Description :
*/
public class LambdaExpressionExample7 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("ankit");
list.add("nmayank");
list.add("irfan");
list.add("jai");
list.forEach((n) -> {
System.out.println(n);
});
}
}
Multiple Statements:
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 10:45
* @Description :
*/
interface Sayable2{
String say(String message);
}
public class LambdaExpressionExample8 {
public static void main(String[] args) {
Sayable2 person = (message) -> {
String str1 = "I would like to say, ";
String str2 = str1 + message;
return str2;
};
System.out.println(person.say("time is precious."));
}
}
Creating Thread(创建线程):
package com.allen.java8;
/**
* @author :jhys
* @date :Created in 2021/7/20 10:48
* @Description :
*/
public class LambdaExpressionExample9 {
public static void main(String[] args) {
//Thread Example without lambda
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Thread1 is running");
}
};
Thread t1 = new Thread(r1);
t1.start();
//Thread Example with lambda
Runnable r2 = () -> {
System.out.println("Thread2 is running...");
};
Thread t2=new Thread(r2);
t2.start();
}
}
Comparator比较器:
package com.allen.java8;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author :jhys
* @date :Created in 2021/7/20 14:07
* @Description :
*/
class Product{
int id;
String name;
float price;
public Product(int id, String name, float price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
}
public class LambdaExpressionExample10 {
public static void main(String[] args) {
List<Product> list = new ArrayList<>();
//Adding Products
list.add(new Product(1,"HP Laptop",25000f));
list.add(new Product(3,"Keyboard",300f));
list.add(new Product(2,"Dell Mouse",150f));
System.out.println("Sorting on the basis of name...");
Collections.sort(list, (p1, p2) -> {
return (int) (p1.price - p2.price);
});
list.forEach((Product p) -> {
System.out.println(p.id+" "+p.name+" "+p.price);
});
}
}
Filter Collection Data:
package com.allen.java8;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* @author :jhys
* @date :Created in 2021/7/20 14:23
* @Description :
*/
class Product1{
int id;
String name;
float price;
public Product1(int id, String name, float price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
}
public class LambdaExpressionExample11 {
public static void main(String[] args) {
List<Product> list=new ArrayList<Product>();
list.add(new Product(1,"Samsung A5",17000f));
list.add(new Product(3,"Iphone 6S",65000f));
list.add(new Product(2,"Sony Xperia",25000f));
list.add(new Product(4,"Nokia Lumia",15000f));
list.add(new Product(5,"Redmi4 ",26000f));
list.add(new Product(6,"Lenevo Vibe",19000f));
// using lambda to filter data
Stream<Product> filter_data = list.stream().filter(p -> p.price > 20000);
filter_data.forEach((Product product) -> {
System.out.println(product.name+": "+product.price);
});
}
}
Java 8 Stream
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
+--------------------+ +------+ +------+ +---+ +-------+ | stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect| +--------------------+ +------+ +------+ +---+ +-------+
生成流
在 Java 8 中, 集合接口有两个方法来生成流:
-
stream() − 为集合创建串行流。
-
parallelStream() − 为集合创建并行流。
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
forEach
Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
map
map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squareList = numbers.stream()
.map(i -> i * i)
.distinct()
.sorted()
.collect(Collectors.toList());
squareList.forEach((Integer item) -> {
System.out.println(item);
});
filter
filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
long count = strings.stream()
.filter((String str) -> str.isEmpty())
.count();
System.out.println(count);
limit
limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
sorted
sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
Collectors
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);
Filtering Collection by using Stream
package com.allen.java8.stream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author :jhys
* @date :Created in 2021/7/20 14:35
* @Description :
*/
class Product{
int id;
String name;
float price;
public Product(int id, String name, float price) {
this.id = id;
this.name = name;
this.price = price;
}
}
public class JavaStreamExample {
public static void main(String[] args) {
List<Product> productsList = new ArrayList<Product>();
//Adding Products
productsList.add(new Product(1,"HP Laptop",25000f));
productsList.add(new Product(2,"Dell Laptop",30000f));
productsList.add(new Product(3,"Lenevo Laptop",28000f));
productsList.add(new Product(4,"Sony Laptop",28000f));
productsList.add(new Product(5,"Apple Laptop",90000f));
List<Float> productPriceList2 = productsList.stream()
.filter((Product p) -> p.price > 30000) // filtering data
.map(p -> p.price) // fetching price
.collect(Collectors.toList()); // collecting as list
System.out.println(productPriceList2);
}
}