Java 8 新特性学习
1、Lambda表达式
优点:
-
允许把函数作为一个方法的参数(函数作为参数传递进方法中)
-
代码简洁紧凑,非常容易并行计算,可能代表未来的编程趋势
-
Lambda表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力
缺点:
-
若不用并行计算,很多时候计算速度没有比传统的for循环快(并行计算有时需要预热才显示出效率优势)
-
不容易调试
-
若其他程序员没有学过lambda表达式,代码难以理解
-
测试代码:
final static String str = "Hello";
public static void main(String[] args) {
LambdaTest test = new LambdaTest();
MathOperation add = (int a,int b) -> a+b;
MathOperation sub = (a,b) -> a-b;
MathOperation mul = (int a,int b) ->{return a*b;};
GreetingService gre = (message) -> System.out.println("Hello" + message);
gre.sayMessage("wkf");
System.out.println(test.operate(10,5,add));
System.out.println(test.operate(10,5,sub));
System.out.println(test.operate(10,5,mul));
GreetingService gs = message ->
System.out.println(str + message);
gs.sayMessage("wkf");
}
interface MathOperation{
int operation(int a, int b);
}
interface GreetingService {
void sayMessage(String message);
}
private int operate(int a, int b, MathOperation mathOperation){
return mathOperation.operation(a, b);
}
2、方法引用
-
方法引用通过方法的名字来指向一个方法
-
方法引用可以使语言的构造更紧凑简介,减少冗余代码
-
方法引用使用一对冒号
::
-
构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下:
-
final Car car = Car.create( Car::new ); final List< Car > cars = Arrays.asList( car );
-
静态方法引用:它的语法是Class::static_method,实例如下:
cars.forEach( Car::collide );
-
特定类的任意对象的方法引用:它的语法是Class::method实例如下:
-
cars.forEach( Car::repair );
-
特定对象的方法引用:它的语法是instance::method实例如下:
final Car police = Car.create( Car::new ); cars.forEach( police::follow );
public static void main(String[] args) {
List<String> names1 = new ArrayList<String>();
names1.add("Google ");
names1.add("RunOob ");
names1.add("TaoBao ");
names1.add("Baidu ");
names1.add("Sina ");
for (String s : names1) {
System.out.print(s);
}
System.out.println();
Collections.sort(names1);
//System.out::print方法作为静态方法来引用
names1.forEach(System.out::print);
}
3、函数式接口
定义:函数式接口是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
-
函数式接口可以被隐式的转换为lambda表达式
-
Java1.8新增的函数接口:
java.util.function
,其中有许多类用来支持java的函数式编程
测试:
//Predicate<T>接受一个输入参数,返回一个布尔值结果。
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12);
// Predicate<Integer> predicate = n -> true
// n 是一个参数传递到 Predicate 接口的 test 方法
// n 如果存在则 test 方法返回 true
eval(list,n-> n%3==0);
}
public static void eval(List<Integer> list, Predicate<Integer> predicate
){
for (Integer n : list) {
if (predicate.test(n)){
System.out.print(n + " ");
}
}
}
4、Java 8 默认方法
定义:默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法,我们只需要在方法名前面加个default关键字即可实现默认方法
Java8的另一个特性是接口可以声明(并且可以提供实现)静态方法
例如:
public interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
// 静态方法
static void blowHorn(){
System.out.println("按喇叭!!!");
}
}
默认方法的使用:
public static void main(String args[]){
Vehicle vehicle = new Car();
vehicle.print();
}
}
interface Vehicle {
default void print(){
System.out.println("我是一辆车!");
}
static void blowHorn(){
System.out.println("按喇叭!!!");
}
}
interface FourWheeler {
default void print(){
System.out.println("我是一辆四轮车!");
}
}
class Car implements Vehicle, FourWheeler {
public void print(){
Vehicle.super.print();
FourWheeler.super.print();
Vehicle.blowHorn();
System.out.println("我是一辆汽车!");
}
5、Stream(流)
-
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据
-
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码
-
这种风格将要处理的元素集合看成一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选、排序、聚合。
Stream:流是一个来自数据源的元素队列并支持聚合操作
-
元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
-
数据源:可以是集合,数组,I/O channel, 产生器 generator 等。
-
聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
Stream操作特性:
-
Pipelining:中间操作都会返回流对象本身,这样多个操作可以串联成一个管道,如同流式风格。这样做可以对操作进行优化,如延迟执行和短路
-
内部迭代:以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。Stream提供了内部迭代的方式,通过访问者模式(Visitor)实现
常用API:
-
生成流:
-
stream()
-- 为集合创建串行流 -
parallelStream()
-- 为集合创建并行流。
-
-
forEach
:迭代流中的每个数据 -
map
:用于映射每个元素到对应的结果 -
filter
:用于通过设置的条件过滤出元素 -
limit
:用于获取指定数量的流 -
sorted
:用于对流进行排序 -
Collectors
:实现了很多归约操作,可用于返回列表或字符串 -
summaryStatistics
:一个产生统计结果的收集器,可以计算平均值,最大值,最小值等
测试代码:
public static void main(String[] args) {
List<String> strings = Arrays.asList("aaa","bbb","def","cc"," ","gh","abc" );
List<String> filtered = strings.stream().filter(
string ->!string.isEmpty()).collect(Collectors.toList());
System.out.println(filtered);
Random random = new Random();
random.ints().limit(3).forEach(System.out::println);
List<Integer> numbers = Arrays.asList(1,2,3,6,7,9,1,5,2);
List<Integer> collect = numbers.stream().map(i -> i * i *2).distinct().sorted().collect(Collectors.toList());
System.out.println(collect);
long count = numbers.stream().filter(number -> number >= 3).count();
System.out.println(count);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println(stats.getMax());
System.out.println(stats.getMin());
System.out.println(stats.getSum());
System.out.println(stats.getAverage());
Map<Integer,String> map = new HashMap<>();
map = strings.stream().collect(Collectors.toMap(str -> strings.indexOf(str),str->str));
map.forEach((key,value) ->{
System.out.println(key + ":" +value);
});
System.out.println(strings.stream().collect(Collectors.joining(", ")));
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)