Java Stream流操作面试题

使用 Java Stream API 编写一个程序来计算列表中元素的累积和
您可以使用 Java Stream API 来计算列表中元素的累积和。这是一个简单的程序来演示这一点:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        List<Integer> cumulativeSum = numbers.stream()
                .mapToInt(Integer::intValue)
                .boxed()
                .collect(Collectors.toList());

        for (int i = 1; i < cumulativeSum.size(); i++) {
            cumulativeSum.set(i, cumulativeSum.get(i) + cumulativeSum.get(i - 1));
        }

        System.out.println("Original List: " + numbers);
        System.out.println("Cumulative Sum: " + cumulativeSum);
    }
}

该程序首先将 List<Integer> 转换为 IntStream,然后将其装箱回 Integer 对象。然后它将元素收集到一个列表中。最后,它迭代列表以计算累积和。


使用 Java Stream API 编写一个程序来查找列表中第 K 个最小的元素
您可以使用 Java Stream API 通过对列表进行排序然后选择第 K 个元素来查找列表中的第 K 个最小元素。这是一个演示这一点的程序:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class KthSmallestElement {

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(10, 2, 6, 8, 4, 12, 7);
        int k = 3; // Find the 3rd smallest element

        int kthSmallest = findKthSmallest(numbers, k);
        System.out.println(
"The " + k + "th smallest element is: " + kthSmallest);
    }

    public static int findKthSmallest(List<Integer> numbers, int k) {
        List<Integer> sortedList = numbers.stream()
                .sorted()
                .collect(Collectors.toList());

        return sortedList.get(k - 1);
    }
}


在此程序中,我们首先创建一个整数列表。然后,我们使用stream()方法将列表转换为流。我们使用sorted()方法对流进行排序,并将排序后的流收集回列表中。最后,我们使用 get(k - 1) 从排序列表中返回第 K 个最小元素,因为索引是从零开始的。


使用 Java Stream API 编写一个程序将多个Map合并为一个Map
您可以使用 Java Stream API 将多个Map映射合并为一个映射。下面是一个简单的例子来演示这一点:

import java.util.*;
import java.util.stream.Collectors;

public class CombineMapsExample {
    public static void main(String[] args) {
        // Creating multiple maps
        Map<String, Integer> map1 = new HashMap<>();
        map1.put(
"A", 1);
        map1.put(
"B", 2);

        Map<String, Integer> map2 = new HashMap<>();
        map2.put(
"C", 3);
        map2.put(
"D", 4);

        Map<String, Integer> map3 = new HashMap<>();
        map3.put(
"E", 5);
        map3.put(
"F", 6);

       
// Combining maps using Java Stream API
        Map<String, Integer> combinedMap = Stream.of(map1, map2, map3)
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

       
// Printing the combined map
        System.out.println(combinedMap);
    }
}

该程序创建三个映射(map1、map2 和 map3),然后使用 Stream API 的 flatMap 操作和 Collectors.toMap 方法将它们组合成一个映射 (combinedMap)。


使用 Java Stream API 编写程序以将列表中的空值替换为默认值
您可以使用 Java Stream API 将列表中的空值替换为默认值。这是一个演示这一点的示例程序:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ReplaceNullValues {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("a", null, "b", null, "c", null);

        List<String> replacedList = list.stream()
                .map(value -> value != null ? value :
"default")
                .collect(Collectors.toList());

        System.out.println(
"Original list: " + list);
        System.out.println(
"List with nulls replaced: " + replacedList);
    }
}


该程序创建一个包含一些空值的列表,然后使用映射函数将每个空值替换为“default”。最后,它将元素收集到一个新列表中。输出将是:
Original list: [a, null, b, null, c, null]
List with nulls replaced: [a, default, b, default, c, default]

使用 Java Stream API 编写一个程序来查找数字列表的中位数
下面是一个使用 Java Stream API 查找数字列表中位数的程序:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MedianCalculator {

    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);
        numbers.add(40);
        numbers.add(50);

        double median = findMedian(numbers);
        System.out.println("Median: " + median);
    }

    public static double findMedian(List<Integer> numbers) {
        Collections.sort(numbers);
        int size = numbers.size();

        if (size % 2 == 0) {
            int mid1 = numbers.get(size / 2 - 1);
            int mid2 = numbers.get(size / 2);
            return (double) (mid1 + mid2) / 2;
        } else {
            return numbers.get(size / 2);
        }
    }
}

该程序首先使用 Collections.sort() 对数字列表进行排序。然后,它根据列表大小是偶数还是奇数来计算中位数。如果大小是偶数,则计算中间两个元素的平均值。如果大小为奇数,则直接返回中间元素。


使用 Java Stream API 编写一个转置矩阵的程序
您可以使用 Java Stream API 转置矩阵,方法是将矩阵转换为行流,然后转置它,最后将转置后的矩阵收集回二维数组。您可以这样做:

import java.util.Arrays;

public class MatrixTranspose {
    public static void main(String[] args) {
        int[][] matrix = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };

        int[][] transposedMatrix = transpose(matrix);

        // Print the transposed matrix
        for (int[] row : transposedMatrix) {
            System.out.println(Arrays.toString(row));
        }
    }

    public static int[][] transpose(int[][] matrix) {
        return Arrays.stream(matrix)
                .reduce((a, b) -> IntStream.range(0, Math.max(a.length, b.length))
                        .mapToObj(i -> i < a.length ? a[i] : new int[a.length])
                        .mapToInt(row -> row.length > 0 ? row[0] : 0)
                        .zipWith(IntStream.range(0, Math.max(a.length, b.length))
                                .mapToObj(i -> i < b.length ? b[i] : new int[b.length])
                                .mapToInt(row -> row.length > 0 ? row[0] : 0), (x, y) -> {
                            int[] result = new int[]{x, y};
                            return result;
                        }))
                .orElse(new int[0][]);
    }
}


该程序将转置给定的矩阵并打印转置后的矩阵。请注意,此方法假设矩阵是矩形(所有行具有相同的长度)。如果您的矩阵不是矩形,您可能需要修改转置方法来处理这种情况。


使用 Java Stream API 编写程序来生成列表的排列
您可以使用 Java Stream API 生成列表的排列,方法是首先创建递归方法来生成排列,然后使用 Stream API 生成所有可能的排列。这是一个例子:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Permutations {

    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3);
        List<List<Integer>> permutations = generatePermutations(list);
        permutations.forEach(System.out::println);
    }

    public static <T> List<List<T>> generatePermutations(List<T> list) {
        if (list.isEmpty()) {
            return List.of(List.of());
        }

        return list.stream()
                .flatMap(element ->
                        generatePermutations(list.stream().filter(e -> !e.equals(element)).collect(Collectors.toList()))
                                .stream()
                                .map(permutation -> {
                                    List<T> perm = new ArrayList<>(permutation);
                                    perm.add(element);
                                    return perm;
                                })
                )
                .collect(Collectors.toList());
    }
}

该程序生成并打印列表 [1, 2, 3] 的所有排列。您可以将 List.of(1, 2, 3) 替换为您想要为其生成排列的任何其他列表。


使用 Java Stream API 编写程序以查找一系列字符中缺失的字符
您可以使用 Java Stream API 从一系列字符中查找丢失的字符。这是一个演示这一点的示例程序:

import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class MissingCharactersFinder {

    public static void main(String[] args) {
        String input = "abcdefghijklmnopqrstuvwxyz";
        String range =
"hijklmnopqrstuvwx";

        String missingCharacters = findMissingCharacters(input, range);
        System.out.println(
"Missing characters: " + missingCharacters);
    }

    public static String findMissingCharacters(String input, String range) {
        return range.chars()
                .filter(c -> input.indexOf(c) == -1)
                .mapToObj(c -> String.valueOf((char) c))
                .collect(Collectors.joining());
    }
}


在此程序中,findMissingCharacters 方法采用两个字符串:输入和范围。它使用 Stream API 将范围字符串转换为字符值的 IntStream。然后,它过滤掉输入字符串中不存在的字符,并将丢失的字符收集到一个新字符串中。最后,它返回包含缺失字符的字符串。

使用 Java Stream API 编写一个程序来计算列表中每个元素的素因数
您可以使用 Java Stream API 计算列表中每个元素的素因数。这是一个演示这一点的程序:

import java.util.ArrayList;
import java.util.List;

public class PrimeFactorsCalculator {

    public static void main(String[] args) {
        List<Integer> numbers = List.of(12, 15, 20, 30, 35);

        numbers.stream()
                .forEach(number -> {
                    System.out.print("Prime factors of " + number + ": ");
                    calculatePrimeFactors(number).forEach(factor -> System.out.print(factor +
" "));
                    System.out.println();
                });
    }

    private static List<Integer> calculatePrimeFactors(int number) {
        List<Integer> primeFactors = new ArrayList<>();
        int divisor = 2;

        while (number > 1) {
            while (number % divisor == 0) {
                primeFactors.add(divisor);
                number /= divisor;
            }
            divisor++;
        }

        return primeFactors;
    }
}

该程序定义了一个方法calculatePrimeFactors,用于计算给定数字的素因数。然后,它使用 Java Stream API 迭代数字列表,为每个数字调用calculatePrimeFactors 并打印结果。 

使用 Java Stream API 编写一个程序来查找多个列表的交集。
您可以使用 Java Stream API 查找多个列表的交集,方法是将列表转换为流,然后使用“reduce”方法查找公共元素。这是一个演示这一点的程序:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<List<Integer>> lists = new ArrayList<>();
        lists.add(Arrays.asList(1, 2, 3, 4, 5));
        lists.add(Arrays.asList(2, 3, 4, 5, 6));
        lists.add(Arrays.asList(3, 4, 5, 6, 7));

        List<Integer> intersection = lists.stream()
                .reduce((list1, list2) -> list1.stream()
                        .filter(list2::contains)
                        .collect(Collectors.toList()))
                .orElse(new ArrayList<>());

        System.out.println("Intersection: " + intersection);
    }
}

    

该程序创建三个整数列表,并使用“reduce”方法找到它们的交集。 “filter”操作用于检查第一个列表中的每个元素是否包含在第二个列表中,而“collect”方法将公共元素收集到一个新列表中。


编写一个程序,使用 Java Stream API 将多个流合并为一个流。
您可以使用 Stream.concat 方法将多个流合并为一个流。这是一个演示这一点的示例程序:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // Create multiple streams
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<Integer> list2 = Arrays.asList(4, 5, 6);
        List<Integer> list3 = Arrays.asList(7, 8, 9);

       
// Combine streams
        Stream<Integer> combinedStream = Stream.concat(
                Stream.concat(list1.stream(), list2.stream()),
                list3.stream()
        );

       
// Collect and print elements from the combined stream
        List<Integer> combinedList = combinedStream.collect(Collectors.toList());
        System.out.println(combinedList);
    }
}


在此示例中,我们有三个列表(“list1”、“list2”和“list3”),我们使用“Stream.concat”方法将它们组合成一个流。最后,我们将组合流的元素收集到一个列表中并打印它们。


使用 Java Stream API 编写一个程序以从列表中删除第 n 个元素
要使用 Java Stream API 从列表中删除第 n 个元素,您可以将列表转换为流,过滤掉第 n 个元素,然后将流收集回列表。这是一个例子:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class RemoveNthElement {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);

        int n = 2; // Remove the 2nd element (index 1)

        List<Integer> updatedList = IntStream.range(0, numbers.size())
                .filter(i -> i != n)
                .mapToObj(numbers::get)
                .collect(Collectors.toList());

        System.out.println(
"Original List: " + numbers);
        System.out.println(
"Updated List: " + updatedList);
    }
}

在这个例子中,我们有一个整数“numbers”列表。我们想要删除索引“n”(从零开始的索引)处的元素。 `IntStream.range` 方法用于创建从 0 到 `numbers.size() - 1` 的索引流。然后,我们使用“filter”方法排除索引“n”,并使用“mapToObj”获取索引对应的元素。最后,我们将流收集回列表以获取更新后的列表,其中不含第 n 个元素。

使用 Java Stream API 编写一个程序来查找两个列表的交集。
您可以使用 Java Stream API 来查找两个列表的交集,方法是将它们转换为流,然后使用过滤器仅保留公共元素。这是一个实现此目的的简单程序:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);

        List<Integer> list2 = new ArrayList<>();
        list2.add(3);
        list2.add(4);
        list2.add(5);
        list2.add(6);

        List<Integer> intersection = findIntersection(list1, list2);
        System.out.println("Intersection: " + intersection);
    }

    public static <T> List<T> findIntersection(List<T> list1, List<T> list2) {
        return list1.stream()
                .filter(list2::contains)
                .collect(Collectors.toList());
    }
}

该程序将输出:

交叉点:[ 3 , 4 ]

此代码采用两个列表 list1 和 list2,并使用 Java Stream API 查找它们的交集。然后它打印出两个列表共有的元素。


使用 Java Stream API 编写一个程序来计算列表中每个元素的阶乘
您可以使用 Java Stream API 计算列表中每个元素的阶乘。这是一个演示这一点的程序:

import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FactorialCalculator {

    public static BigInteger factorial(int n) {
        if (n == 0 || n == 1) {
            return BigInteger.ONE;
        }
        return BigInteger.valueOf(n).multiply(factorial(n - 1));
    }

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        List<BigInteger> factorials = numbers.stream()
                .map(n -> factorial(n))
                .collect(Collectors.toList());

        System.out.println("Factorials: " + factorials);
    }
}


在这个程序中,我们首先定义一个阶乘方法来使用递归计算给定数字的阶乘。然后,我们创建一个整数列表,并使用stream方法将列表转换为流。我们使用map方法对流中的每个元素应用阶乘方法,最后使用collect方法将结果收集到列表中。


使用 Java Stream API 编写程序以按多个条件对列表中的对象进行分组
您可以使用 Java Stream API 通过链接“Collectors.groupingBy”收集器按多个条件对列表中的对象进行分组。这是一个演示这一点的示例程序:

import java.util.*;
import java.util.stream.Collectors;

class Student {
    private String name;
    private int age;
    private String department;

    public Student(String name, int age, String department) {
        this.name = name;
        this.age = age;
        this.department = department;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getDepartment() {
        return department;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", department='" + department + '\'' +
                '}';
    }
}

public class Main {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student("Alice", 20, "Math"),
                new Student("Bob", 21, "Math"),
                new Student("Charlie", 22, "Physics"),
                new Student("David", 20, "Physics"),
                new Student("Eve", 21, "Physics")
        );

        Map<String, Map<Integer, List<Student>>> groupedStudents = students.stream()
                .collect(Collectors.groupingBy(Student::getDepartment,
                        Collectors.groupingBy(Student::getAge)));

        groupedStudents.forEach((department, ageMap) -> {
            System.out.println("Department: " + department);
            ageMap.forEach((age, studentList) -> {
                System.out.println("\tAge: " + age);
                studentList.forEach(System.out::println);
            });
        });
    }
}
在此示例中,“Student学生”对象首先按部门分组,然后按年龄分组。 “groupedStudents”映射包含此分组的结果,其中外部映射的键是部门,内部映射的键是年龄。内部映射的值是符合院系和年龄标准的学生列表。


使用 Java Stream API 编写程序以查找列表中最接近的元素对
要使用 Java Stream API 查找列表中最接近的元素对,您可以创建一个自定义方法来比较列表中的所有元素对并返回差异最小的对。这是实现此目的的示例程序:

import java.util.*;
import java.util.stream.*;

public class ClosestPair {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 4, 7, 10, 15);

        Optional<Pair> closestPair = findClosestPair(numbers);
        if (closestPair.isPresent()) {
            System.out.println("Closest pair: " + closestPair.get());
        } else {
            System.out.println(
"No pair found");
        }
    }

    public static Optional<Pair> findClosestPair(List<Integer> numbers) {
        return IntStream.range(0, numbers.size() - 1)
                .flatMap(i -> IntStream.range(i + 1, numbers.size())
                        .mapToObj(j -> new Pair(numbers.get(i), numbers.get(j))))
                .min(Comparator.comparingInt(Pair::getDifference));
    }

    static class Pair {
        private final int first;
        private final int second;

        public Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public int getDifference() {
            return Math.abs(first - second);
        }

        @Override
        public String toString() {
            return
"(" + first + ", " + second + ")";
        }
    }
}

该程序定义了一个“Pair”类来保存一对整数并计算它们之间的差。 “findClosestPair”方法生成列表中的所有元素对,并使用 Stream API 的“min”方法查找差异最小的对。

编写一个程序,使用 Java Stream API 将多个列表合并并排序为单个排序列表
要使用 Java Stream API 将多个列表合并并排序为单个排序列表,您可以遵循以下方法:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MergeAndSortLists {
    public static void main(String[] args) {
        List<Integer> list1 = Arrays.asList(1, 4, 7);
        List<Integer> list2 = Arrays.asList(2, 5, 8);
        List<Integer> list3 = Arrays.asList(3, 6, 9);

        List<Integer> mergedAndSorted = Stream.of(list1, list2, list3)
                .flatMap(List::stream)
                .sorted()
                .collect(Collectors.toList());

        System.out.println("Merged and Sorted List: " + mergedAndSorted);
    }
}

该程序首先创建三个包含整数值的列表(list1、list2 和 list3)。然后,它使用 flatMap() 将这些列表合并到单个流中,使用 Sorted() 对流进行排序,并使用 Collectors.toList() 将排序后的元素收集到新列表中。最后,它打印合并和排序的列表。

编写一个程序,将逗号分隔的字符串拆分为各个元素,并使用 Java Stream API 过滤掉空字符串
您可以使用 Java Stream API 来实现此目的,方法是拆分逗号分隔的字符串,然后过滤掉空字符串。下面是一个示例程序来演示这一点:

import java.util.Arrays;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        String input = "apple,banana,,orange,,";
        String[] elements = input.split(
",");

        Stream<String> stream = Arrays.stream(elements)
                .filter(s -> !s.isEmpty());

        stream.forEach(System.out::println);
    }
}


该程序使用 split(",") 方法将输入字符串“apple,banana,,orange,,”拆分为各个元素,从而生成一个包含 ["apple", "banana", "", "orange" 的数组元素”,“”]。然后,它使用 Arrays.stream(elements) 从数组创建一个流,并使用 filter 方法过滤掉空字符串。最后,它使用 forEach(System.out::println) 打印每个非空元素。

使用 Java Stream API 编写一个程序,根据自定义比较器对对象列表进行排序
您可以使用 Java Stream API 和自定义比较器对对象列表进行排序。这是一个例子:

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
               
"name='" + name + '\'' +
               
", age=" + age +
                '}';
    }
}

public class Main {
    public static void main(String[] args) {
        List<Person> persons = Arrays.asList(
                new Person(
"Alice", 30),
                new Person(
"Bob", 25),
                new Person(
"Charlie", 35)
        );

        Comparator<Person> ageComparator = Comparator.comparingInt(Person::getAge);

        List<Person> sortedPersons = persons.stream()
                .sorted(ageComparator)
                .collect(Collectors.toList());

        sortedPersons.forEach(System.out::println);
    }
}

    

在此示例中,我们有一个包含姓名和年龄字段的 Person 类。我们创建一个 Person 对象列表,然后使用 Stream 类的排序方法以及自定义比较器 (ageComparator) 根据人员的年龄对列表进行排序。最后,我们使用 Collectors.toList() 将排序后的元素收集到一个新列表中,并打印排序后的列表。

使用 Java Stream API 编写一个程序来从字符串列表中过滤字谜。
您可以使用 Java Stream API 从字符串列表中过滤字谜,方法是按排序形式对字符串进行分组,然后过滤掉仅包含一个元素的组。您可以这样做:

import java.util.*;
import java.util.stream.Collectors;

public class AnagramFilter {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("listen", "pot", "part", "opt", "trap", "silent", "top", "this", "hello", "hits");
        Map<String, List<String>> anagramGroups = words.stream()
                .collect(Collectors.groupingBy(str -> sortString(str)));

        List<String> anagrams = anagramGroups.values().stream()
                .filter(group -> group.size() > 1)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        System.out.println(
"Anagrams: " + anagrams);
    }

    private static String sortString(String str) {
        char[] charArray = str.toCharArray();
        Arrays.sort(charArray);
        return new String(charArray);
    }
}


在此程序中,sortString方法用于对字符串的字符进行排序,该方法将用作groupingBy收集器中的键将字谜词分组在一起。生成的 anagrams 列表将包含输入列表中彼此互为 anagrams 的所有字符串。