Java8 Stream编码问题
我最近参加了多次 Java 开发人员职位的面试。这些面试中反复出现的主题是基于场景的编程问题,重点关注 Java 8 Streams。成功回答这些问题不仅表明您的实践经验,还表明您对 Streams 的理解。
本文将介绍 Stream 上的各种编程问题。我相信,一旦你看完下面的问题,你将能够回答面试中关于 Stream 的任何其他问题。
1.在 List<Integer> 中查找最大值。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);1 , 2 , 3 , 4 , 5 );
int max = numbers.stream()
.max(Integer::compareTo)
// 以上代码使用方法 referene,
// 以下注释代码使用 lamnda 表达式。
// numbers.stream().max((a, b) -> a.compareTo(b));
System.out.println(max); // 输出:5
2. 给定 List<Employee>,查找薪水最高的员工。
List<Employee> employees = Arrays.asList(
new Employee("John", 50000),new Employee("John", 50000),
new Employee("Jane", 60000),
new Employee("Mark", 55000),
new Employee("Sophia", 75000),
new Employee("Alex", 40000)
);
Optional<Employee> highestSalaryEmployee = employees.stream()
.max(Comparator.comparingDouble(Employee::getSalary));
highestSalaryEmployee.ifPresent(System.out::println);
// Output
// Employee{name='Sophia', salary=75000.0}
3. 给定 List<String>,返回连接 List 所有字符串的字符串。
List<String> words = Arrays.asList("apple", "banana", "cherry");"apple", "banana", "cherry");
String result = words.stream()
.collect(Collectors.joining(", "));
System.out.println(result);
// Output: apple, banana, cherry
4. 根据 List<Integer> 的均匀性对其进行分组。(偶数或奇数)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);1, 2, 3, 4, 5, 6);
Map<Boolean, List<Integer>> grouped = numbers.stream()
.collect(Collectors.groupingBy(n -> n % 2 == 0));
System.out.println(grouped);
// Output: {false=[1, 3, 5], true=[2, 4, 6]}
Collectors.groupingBy
:这是一个根据分类器函数对流元素进行分组的收集器。
分类器函数:lambda 表达式n -> n % 2 == 0
检查数字是否为偶数。如果为偶数,则返回结果;如果为奇数true
,则返回结果。false
结果,流将被分成两组:一组为条件为true
(偶数)的数字,另一组为条件为false
(奇数)的数字。
5. 给定 List<Employee>,按职位对其进行分组。
List<Employee> employees = Arrays.asList(
new Employee("Alice", "Developer"), new Employee ( "Alice" , "Developer" ),
new Employee ( "Bob" , "Manager" ),
new Employee ( "Charlie" , "Developer" ),
new Employee ( "David" , "Manager" ),
new Employee ( "Eve" , "Designer" )
);
Map<String, List<Employee> groupedByDesignation = employees.stream()
.collect(Collectors.groupingBy(Employee::getDesignation));
// 输出
// 开发人员:[员工{name='Alice', designation='Developer'}, 员工{name='Charlie', designation='Developer'}]
// 经理:[员工{name='Bob', designation='Manager'}, 员工{name='David', designation='Manager'}]
// 设计师:[员工{name='Eve', designation='Designer'}]
6. 给定 List<String>,计算长度大于 4 的字符串的数量
List<String> words = Arrays.asList("apple", "banana", "kiwi", "cherry"); "apple" , "banana" , "kiwi" , "cherry" );
long count = words.stream()
.filter(w -> w.length() > 4 )
.count();
System.out.println(count);
// 输出:3
7. 按字母相反的顺序对 List<String> 进行排序。
List<String> words = Arrays.asList("apple", "banana", "cherry"); "apple" , "banana" , "cherry" );
List<String> sortedWords = words.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
System.out.println(sortedWords);
// 输出:[cherry, banana, apple]
8. 找到所有不同的元素。
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5); 1 , 2 , 2 , 3 , 4 , 4 , 5 );
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctNumbers); // 输出:[1, 2, 3, 4, 5]
9.检查 List<Integer> 中的所有元素是否都是正数。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); 1 , 2 , 3 , 4 , 5 );
boolean allPositive = numbers.stream()
.allMatch(n -> n > 0 );
System.out.println(allPositive);
// 输出:true
10. 如何按薪水对 List<Employee> 进行排序
// 获取按薪水排序的新列表 List
<Employee> sortedEmployees = employees.stream()
.sorted(Comparator.comparing(Employee::getSalary))
.collect(Collectors.toList());
11. 给定 List<String>,查找关键词
List<String> words = Arrays.asList("listen", "silent", "enlist", "rat", "tar", "god", "dog", "evil", "vile", "veil"); "listen" , "silent" , "enlist" , "rat" , "tar" , "god" , "dog" , "evil" , "vile" , "veil" );
Map<String, List<String>> anagrams = words.stream()
.collect(Collectors.groupingBy(word -> {
char [] charArray = word.toCharArray();
Arrays.sort(charArray); // 对字符进行排序
return new String (charArray); // 返回排序后的字符串
}));
anagrams.values().stream()
.filter(group -> group.size() > 1 ) // 仅过滤具有多个字谜的组
.forEach(System.out::println); // 输出字谜组
// 输出
// [silent, listen, enlist]
// [tar, rat]
// [dog, god]
// [vile, evil, veil]
12. 生成斐波那契数列
// 生成前 10 个斐波那契数
Stream.iterate( new long []{ 0 , 1 }, fib -> new long []{fib[ 1 ], fib[ 0 ] + fib[ 1 ]})
.limit( 10 ) // 限制为前 10 个数字
.map(n -> n[ 0 ]) // 提取每对的第一个元素
.forEach(System.out::println);
13. 给定 List<Employee>,获取一个包含部门和员工姓名的 Map,并绘制该部门的最高工资。
Map<String, String> highestSalaryEmployees = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)),
emp -> emp.map(Employee::getName).orElse(null) null )
)
));
14. 给定 List<Employee>,返回包含员工姓名和薪水的 Map
Map<String, Double> employeeSalaryMap = employees.stream()
.collect(Collectors.toMap(Employee::getName, Employee::getSalary);
15. 给定 List<Employee>,从列表中删除同名的员工。
Set<String> seenNames = new HashSet<>(); new HashSet <>();
List<Employee> uniqueEmployees = employees.stream()
.filter(emp -> seenNames.add(emp.getName())) // 将名称添加到集合并过滤重复项
.collect(Collectors.toList()); // 收集到列表
16. 假设List<Employee>
每个人都Employee
拥有List<String>
技能。使用flatMap
创建List<String>
包含所有员工所有独特技能的表格。
List<String> uniqueSkills = employees.stream()
.flatMap(emp -> emp.getSkills().stream())
.distinct()
.collect(Collectors.toList());
17. 用来从句子列表中flatMap
创建所有单个单词。List<String>
List<String> sentences = Arrays.asList("Hello world", "Java 8 Streams", "flatMap example"); "Hello world" , "Java 8 Streams" , "flatMap example" );
List<String> words = sentences.stream()
.flatMap(sentence -> Arrays.stream(sentence.split( " " )))
.collect(Collectors.toList());
System.out.println(words);
// 输出:[Hello, world, Java, 8, Streams, flatMap, example]
18. 给定 List<Integer>,查找总和等于给定目标数字的数字对。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); 1 , 2 , 3 , 4 , 5 , 6 );
int target = 7 ;
List<List<Integer>> pair = numbers.stream()
.flatMap(num1 -> numbers.stream()
.filter(num2 -> num1 + num2 == target)
.map(num2 -> Arrays.asList(num1, num2)))
.collect(Collectors.toList());
// 输出
// [1, 6]
// [2, 5]
// [3, 4]
19. 找出薪水第二高的员工List<Employee>
List<Employee> employees = Arrays.asList(
new Employee("Alice", 70000), new Employee ( " Alice" , 70000 ),
new Employee ( "Bob" , 80000 ),
new Employee ( "Charlie" , 60000 ),
new Employee ( "David" , 90000 ),
new Employee ( "Eve" , 80000 )
);
Optional<Employee> secondHighest = employees.stream()
.sorted(Comparator.comparingDouble(Employee::getSalary).reversed())
.distinct() // 避免薪水相等时出现重复
.skip( 1 ) // 跳过最高薪水
.findFirst(); // 获取第二高的薪水
// 输出
// Employee{name='Bob', salary=80000.0}