请教Java中的Lambda表达式有什么用?

本文通过实测对比了Java中使用Lambda表达式与其他传统循环、迭代器及多线程处理方式在性能上的表现。实验涉及随机数过滤、最大值查找等场景,结果显示Lambda及其流操作并未带来显著的性能提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、问题

不明白Java为什么要引入Lambda表达式。只有在很少的情况下用它来替换匿名类可能会少那么三、四行代码,可是,我们成千上万的代码都写了,谁会在乎这么一点呢?并且,Lambda表达式限制条件比匿名类多,匿名类它是类,类是面向对象语言的核心,它比Lambda表达式功能强多了。

Lambda与性能也没有什么关系。想提高性能要优化算法、充分利用计算资源,与Lambda表达式有什么关系呢?

还有说引入面向函数式编程思想,这个也没看出来。

2、测试结果

首先做个测试。用随机数填充集合,然后遍历集合,取出能被2整除的数字并保存在中间结果中,再从中间结果取出最大的数。分别用了迭代器、外循环、内循环、集合普通流、集合并行流、自定义多线程,结果如下:

使用lambda表达式后,代码没变少、没更可读、性能也没更高。最后一种方式因为要自己处理多线程问题,代码量变多。但自已实现的话好像更加灵活。

3、代码

第一种迭代器:

package com.xxxxxx.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

public class Lambda0 {

	private ArrayList<Integer> srcArray = new ArrayList<Integer>();

	public static void main(String[] args) {
		// 初始化srcArray数组
		Lambda0 lam0 = new Lambda0();
		Random rand = new Random();
		for (int i = 0; i < 100000; i++) {
			lam0.srcArray.add(rand.nextInt(100000));
		}
		// 开始计时
		long start = System.currentTimeMillis();
		// midArray用来保存中间结果
		ArrayList<Integer> midArray = new ArrayList<Integer>();
		Iterator<Integer> iter = lam0.srcArray.iterator();
		// 使用迭代器
		while (iter.hasNext()) {
			// 这个循环用来消耗时间
			for (int l = 0; l < 1000000; l++) {
				if ((l % 2) == 0) {
					l = l * 2;
					l = l / 2;
				}
			}
			// 将srcArray中能被2整除的数放在midArray数组中
			Integer value = iter.next();
			if ((value % 2) == 0) {
				midArray.add(value);
			}
		}
		// 从midArray中找出最大的整数
		class Max {
			public int value = 0;
		}
		Max max = new Max();
		// 使用迭代器
		iter = midArray.iterator();
		while (iter.hasNext()) {
			Integer value = iter.next();
			if (value > max.value) {
				max.value = value;
			}
		}
		// 计时结束
		long end = System.currentTimeMillis();
		// 输出结果
		System.out.println("[Max]" + max.value + ",[time]" + (end - start));
	}
}

第二种外循环:

package com.xxxxxx.test;

import java.util.ArrayList;
import java.util.Random;

public class Lambda1 {

	private ArrayList<Integer> srcArray = new ArrayList<Integer>();

	public static void main(String[] args) {
		// 初始化srcArray数组
		Lambda1 lam1 = new Lambda1();
		Random rand = new Random();
		for (int i = 0; i < 100000; i++) {
			lam1.srcArray.add(rand.nextInt(100000));
		}
		// 开始计时
		long start = System.currentTimeMillis();
		// midArray用来保存中间结果
		ArrayList<Integer> midArray = new ArrayList<Integer>();
		for (Integer i : lam1.srcArray) {
			// 这个循环用来消耗时间
			for (int l = 0; l < 1000000; l++) {
				if ((l % 2) == 0) {
					l = l * 2;
					l = l / 2;
				}
			}
			// 将srcArray中能被2整除的数放在midArray数组中
			if ((i % 2) == 0) {
				midArray.add(i);
			}
		}
		// 从midArray中找出最大的整数
		Integer max = 0;
		for (Integer i : midArray) {
			if (i > max) {
				max = i;
			}
		}
		// 计时结束
		long end = System.currentTimeMillis();
		// 输出结果
		System.out.println("[Max]" + max + ",[time]" + (end - start));
	}
}

第三种内循环:

package com.xxxxxx.test;

import java.util.ArrayList;
import java.util.Random;

public class Lambda2 {

	private ArrayList<Integer> srcArray = new ArrayList<Integer>();

	public static void main(String[] args) {
		// 初始化srcArray数组
		Lambda2 lam2 = new Lambda2();
		Random rand = new Random();
		for (int i = 0; i < 100000; i++) {
			lam2.srcArray.add(rand.nextInt(100000));
		}
		// 开始计时
		long start = System.currentTimeMillis();
		// midArray用来保存中间结果
		ArrayList<Integer> midArray = new ArrayList<Integer>();
		lam2.srcArray.forEach((i) -> {
			// 这个循环用来消耗时间
			for (int l = 0; l < 1000000; l++) {
				if ((l % 2) == 0) {
					l = l * 2;
					l = l / 2;
				}
			}
			// 将srcArray中能被2整除的数放在midArray数组中
			if ((i % 2) == 0) {
				midArray.add(i);
			}
		});
		// 从midArray中找出最大的整数
		class Max {
			public int value = 0;
		}
		Max max = new Max();
		// 直接使用Integer max = 0不行
		midArray.forEach((i) -> {
			if (i > max.value) {
				max.value = i;
			}
		});
		// 计时结束
		long end = System.currentTimeMillis();
		// 输出结果
		System.out.println("[Max]" + max.value + ",[time]" + (end - start));
	}
}

第四种集合stream:

package com.xxxxxx.test;

import java.util.ArrayList;
import java.util.Random;

public class Lambda3 {

	private ArrayList<Integer> srcArray = new ArrayList<Integer>();

	public static void main(String[] args) {
		// 初始化srcArray数组
		Lambda3 lam3 = new Lambda3();
		Random rand = new Random();
		for (int i = 0; i < 100000; i++) {
			lam3.srcArray.add(rand.nextInt(100000));
		}
		// 开始计时
		long start = System.currentTimeMillis();
		// midArray用来保存中间结果,流处理不需要
		// ArrayList<Integer> midArray = new ArrayList<Integer>();
		class Max {
			public int value = 0;
		}
		Max max = new Max();
		// 普通流
		lam3.srcArray.stream().filter((i) -> {
			// 这个循环用来消耗时间
			for (int l = 0; l < 1000000; l++) {
				if ((l % 2) == 0) {
					l = l * 2;
					l = l / 2;
				}
			}
			if ((i % 2) == 0) {
				return true;
			} else {
				return false;
			}
		}).forEach((i) -> {
			// 从流中找出最大的整数
			if (i > max.value) {
				max.value = i;
			}
		});
		// 计时结束
		long end = System.currentTimeMillis();
		// 输出结果
		System.out.println("[Max]" + max.value + ",[time]" + (end - start));
	}
}

第五种集合并行stream:

package com.xxxxxx.test;

import java.util.ArrayList;
import java.util.Random;

public class Lambda4 {

	private ArrayList<Integer> srcArray = new ArrayList<Integer>();

	public static void main(String[] args) {
		// 初始化srcArray数组
		Lambda4 lam4 = new Lambda4();
		Random rand = new Random();
		for (int i = 0; i < 100000; i++) {
			lam4.srcArray.add(rand.nextInt(100000));
		}
		// 开始计时
		long start = System.currentTimeMillis();
		// midArray用来保存中间结果,流处理不需要
		// ArrayList<Integer> midArray = new ArrayList<Integer>();
		class Max {
			public int value = 0;
		}
		Max max = new Max();
		// 并发流
		lam4.srcArray.parallelStream().filter((i) -> {
			// 这个循环用来消耗时间
			for (int l = 0; l < 1000000; l++) {
				if ((l % 2) == 0) {
					l = l * 2;
					l = l / 2;
				}
			}
			if ((i % 2) == 0) {
				return true;
			} else {
				return false;
			}
		}).forEach((i) -> {
			// 从流中找出最大的整数
			if (i > max.value) {
				max.value = i;
			}
		});
		// 计时结束
		long end = System.currentTimeMillis();
		// 输出结果
		System.out.println("[Max]" + max.value + ",[time]" + (end - start));
	}
}

第六种自定义多线程:

package com.xxxxxx.test;

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class Lambda5 {

	private ArrayList<Integer> srcArray = new ArrayList<Integer>();

	public static void main(String[] args) {
		// 初始化srcArray数组
		Lambda5 lam5 = new Lambda5();
		Random rand = new Random();
		for (int i = 0; i < 100000; i++) {
			lam5.srcArray.add(rand.nextInt(100000));
		}
		// 取得CPU核数,本机是4核
		int nThreads = Runtime.getRuntime().availableProcessors();
		// 用于等待多线和结束
		final CountDownLatch threadsCount = new CountDownLatch(nThreads);
		// 实现Runnable的内部类
		class MyRunnable implements Runnable {
			int start = 0;
			int end = 0;
			Integer max = 0;
			MyRunnable(int start, int end) {
				this.start = start;
				this.end = end;
			}
			public void run() {
				// midArray用来保存中间结果
				ArrayList<Integer> midArray = new ArrayList<Integer>();
				ArrayList<Integer> tempArray = new ArrayList<Integer>(lam5.srcArray.subList(start, end));
				for(Integer i : tempArray) {
					// 这个循环用来消耗时间
					for (int l = 0; l < 1000000; l++) {
						if ((l % 2) == 0) {
							l = l * 2;
							l = l / 2;
						}
					}
					if ((i % 2) == 0) {
						midArray.add(i);
					}
				}
				for (Integer i : midArray) {
					if (i > max) {
						max = i;
					}
				}
				threadsCount.countDown(); 
			}
		}
		// 开始计时
		long start = System.currentTimeMillis();
		// 有可能出现小数,因此加1补足
		int step = lam5.srcArray.size() / nThreads + 1;
		// 保存线程对象
		ArrayList<MyRunnable> threadsArrayList = new ArrayList<MyRunnable>();  
		for(int i = 0; i < nThreads; i ++) {
			int startIndex = i * step;
			int endIndex = (i + 1) * step < lam5.srcArray.size() ? (i + 1) * step : lam5.srcArray.size();
			MyRunnable temp = new MyRunnable(startIndex, endIndex);
			threadsArrayList.add(temp);
			new Thread(temp).start();
		}
		// 等待所有线和结束
		try {
			threadsCount.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// 找出最大整数
		int max = 0;
		for (MyRunnable i : threadsArrayList) {
			if (i.max > max) {
				max = i.max;
			}
		}
		// 计时结束
		long end = System.currentTimeMillis();
		// 输出结果
		System.out.println("[Max]" + max + ",[time]" + (end - start));
	}
}

 

Java中,Lambda表达式提供了一种简洁的方式来表示只包含一个方法的接口(也称为函数式接口)的实例。Lambda表达式可以极大地简化代码,特别是当你使用匿名内部类时。Lambda表达式的基本语法是: ``` (parameters) -> expression 或 (parameters) -> { statements; } ``` 下面是一个使用Lambda表达式简化代码的例子: 假设我们有一个`Comparator`接口的匿名内部类实例,用于比较两个字符串的长度: ```java Comparator<String> comparator = new Comparator<String>() { @Override public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }; ``` 使用Lambda表达式,可以将上述匿名内部类替换为以下形式的代码: ```java Comparator<String> comparator = (s1, s2) -> Integer.compare(s1.length(), s2.length()); ``` 这个Lambda表达式替代了原有的`compare`方法的实现,使得代码更加简洁明了。 Lambda表达式还允许你直接使用方法引用和构造函数引用,进一步简化代码。例如,如果你想对一个列表进行排序,使用Lambda表达式可以写为: ```java List<String> list = Arrays.asList("Apple", "Orange", "Banana", "Pear"); list.sort((s1, s2) -> s1.compareTo(s2)); ``` 或者,使用方法引用来进一步简化: ```java list.sort(String::compareTo); ``` 在Java 8及以后的版本中,Lambda表达式配合Stream API可以实现更加流畅和高效的数据处理: ```java List<String> fruits = list.stream() .filter(f -> f.startsWith("A")) .map(String::toUpperCase) .collect(Collectors.toList()); ``` 这里使用了`filter`和`map`方法的Lambda表达式,对列表进行过滤和转换,然后收集结果。 使用Lambda表达式的好处是代码更加简洁,并且能够提高代码的可读性和可维护性。但是,需要注意的是Lambda表达式只适用于函数式接口,这些接口只能有一个抽象方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值