Java8 StreamApi 常用重要功能封装工具类

封装Java8 StreamApi常用的使用方法,工具类代码如下:

import java.math.BigDecimal;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Java8 StreamAPI 常用方法封装
 *
 * @author *** 2020/12/18
 */
public class StreamApiUtil {
    /**
     * 集合转换为List
     *
     * @param collection  集合对象
     * @param valueMapper value映射规则
     * @param <E>         集合元素类型的泛型
     * @param <V>         最终输出类型的泛型
     * @return List<V>
     */
    public static <E, V> List<V> mapList(Collection<E> collection, Function<E, V> valueMapper) {
        if (collection == null) {
            return null;
        }
        return collection.stream().map(valueMapper).collect(Collectors.toList());
    }

    /**
     * 集合转换为Set
     *
     * @param collection  集合对象
     * @param valueMapper value映射规则
     * @param <E>         集合元素类型的泛型
     * @param <V>         最终输出类型的泛型
     * @return Set<V>
     */
    public static <E, V> Set<V> mapSet(Collection<E> collection, Function<E, V> valueMapper) {
        if (collection == null) {
            return null;
        }
        return collection.stream().map(valueMapper).collect(Collectors.toSet());
    }

    /**
     * 集合转换为Map
     *
     * @param collection  集合对象
     * @param keyMapper   Key的映射规则
     * @param valueMapper value映射规则
     * @param <K>         Key的泛型
     * @param <E>         集合元素类型的泛型
     * @param <V>         最终输出类型的泛型
     * @return Map<K, V>
     */
    public static <K, E, V> Map<K, V> toMap(Collection<E> collection, Function<E, K> keyMapper, Function<E, V> valueMapper) {
        if (collection == null) {
            return null;
        }
        return collection.stream().collect(Collectors.toMap(keyMapper, valueMapper));
    }

    public static <K, E> Map<K, E> toMap(Collection<E> collection, Function<E, K> keyMapper) {
        return toMap(collection, keyMapper, Function.identity());
    }
    
	/**
     * 按照指定Key进行分组
     *
     * @param collection 集合对象
     * @param keyMapper  Key的映射规则
     * @param <K>        Key的泛型
     * @param <E>        集合元素类型的泛型
     * @return Map<K, List < E>>
     */
    public static <K, E> Map<K, List<E>> groupBy(Collection<E> collection, Function<E, K> keyMapper) {
        if (collection == null) {
            return null;
        }
        return collection.stream().collect(Collectors.groupingBy(keyMapper, Collectors.toList()));
    }

    /**
     * 集合根据指定的Key规则进行分组求最大值(比如:按照用户ID分组,取每个用户的最近的订单数据 或者 按照用户ID分组,统计每个用户某个属性的最大值)
     *
     * @param collection  集合对象
     * @param keyMapper   分组Key的映射规则
     * @param valueMapper value映射规则
     * @param comparator  集合合并的比较器
     * @return Map<K, V>
     */
    public static <K, E, V> Map<K, V> maxByGroup(Collection<E> collection, Function<E, K> keyMapper, Function<E, V> valueMapper, Comparator<V> comparator) {
        return merge(collection, keyMapper, valueMapper, BinaryOperator.maxBy(comparator));
    }

    public static <K, E> Map<K, E> maxByGroup(Collection<E> collection, Function<E, K> keyMapper, Comparator<E> comparator) {
        return merge(collection, keyMapper, Function.identity(), BinaryOperator.maxBy(comparator));
    }

    /**
     * 集合根据指定的Key规则进行分组求最小值(比如:按照用户ID分组,取每个用户的最早的历史数据 或者 按照用户ID分组,统计每个用户某个属性的最小值)
     *
     * @param collection  集合对象
     * @param keyMapper   分组Key的映射规则
     * @param valueMapper value映射规则
     * @param comparator  集合合并的比较器
     * @return Map<K, V>
     */
    public static <K, E, V> Map<K, V> minByGroup(Collection<E> collection, Function<E, K> keyMapper, Function<E, V> valueMapper, Comparator<V> comparator) {
        return merge(collection, keyMapper, valueMapper, BinaryOperator.minBy(comparator));
    }

    public static <K, E> Map<K, E> minByGroup(Collection<E> collection, Function<E, K> keyMapper, Comparator<E> comparator) {
        return merge(collection, keyMapper, Function.identity(), BinaryOperator.minBy(comparator));
    }
   /**
     * 集合对象的最大值
     *
     * @param collection 集合对象
     * @param comparator 集合合并的比较器
     * @return E
     */
    public static <E> E max(Collection<E> collection, Comparator<E> comparator) {
        if (collection == null) {
            return null;
        }
        Optional<E> maxResult = collection.stream().reduce(BinaryOperator.maxBy(comparator));
        return maxResult.orElse(null);
    }

    /**
     * 集合对象的最小值
     *
     * @param collection 集合对象
     * @param comparator 集合合并的比较器
     * @return E
     */
    public static <E> E min(Collection<E> collection, Comparator<E> comparator) {
        if (collection == null) {
            return null;
        }
        Optional<E> minResult = collection.stream().reduce(BinaryOperator.minBy(comparator));
        return minResult.orElse(null);
    }
    
    /**
     * 集合根据指定的Key规则进行分组求和(比如:按照用户ID分组,取每个用户的余额总值)
     *
     * @param collection  集合对象
     * @param keyMapper   分组Key的映射规则
     * @param valueMapper value映射规则
     * @return Map<K, Integer>
     */
    public static <K, E> Map<K, Integer> sumIntegerByGroup(Collection<E> collection, Function<E, K> keyMapper, Function<E, Integer> valueMapper) {
        return merge(collection, keyMapper, valueMapper, Integer::sum);
    }

    public static <K, E> Map<K, Long> sumLongByGroup(Collection<E> collection, Function<E, K> keyMapper, Function<E, Long> valueMapper) {
        return merge(collection, keyMapper, valueMapper, Long::sum);
    }

    public static <K, E> Map<K, Double> sumDoubleByGroup(Collection<E> collection, Function<E, K> keyMapper, Function<E, Double> valueMapper) {
        return merge(collection, keyMapper, valueMapper, Double::sum);
    }

    /**
     * 集合根据指定的Key规则进行分组计数(比如:按照订单状态分组,统计订单的条数)
     *
     * @param collection  集合对象
     * @param keyMapper   分组Key的映射规则
     * @return Map<K, Long>
     */
    public static <K, E> Map<K, Long> countingByGroup(Collection<E> collection, Function<E, K> keyMapper) {
        if (collection == null) {
            return null;
        }
        if (collection.isEmpty()) {
            return new HashMap<>();
        }
        return collection.stream().collect(Collectors.groupingBy(keyMapper, Collectors.counting()));
    }

    /**
     * 集合根据指定的Key规则进行分组合并
     *
     * @param collection     集合对象
     * @param keyMapper      分组Key的映射规则
     * @param valueMapper    value映射规则
     * @param binaryOperator 自定义集合合并的规则
     * @param <K>            Key的泛型
     * @param <E>            集合元素类型的泛型
     * @param <V>            最终输出类型的泛型
     * @return Map<K, V>
     */
    public static <K, E, V> Map<K, V> merge(Collection<E> collection, Function<E, K> keyMapper, Function<E, V> valueMapper, BinaryOperator<V> binaryOperator) {
        if (collection == null) {
            return null;
        }
        if (collection.isEmpty()) {
            return new HashMap<>();
        }
        return collection.stream().collect(Collectors.toMap(keyMapper, valueMapper, binaryOperator));
    }

    /**
     * 集合元素求和
     *
     * @param collection 集合对象
     * @return Integer
     */
    public static int sumInteger(Collection<Integer> collection) {
        return sum(collection, Integer::sum, 0);
    }

    public static long sumLong(Collection<Long> collection) {
        return sum(collection, Long::sum, 0L);
    }

    public static double sumDouble(Collection<Double> collection) {
        return sum(collection, Double::sum, 0.d);
    }

    /**
     * 集合元素求和
     *
     * @param collection     集合对象
     * @param keyMapper      需要求和的属性映射
     * @param binaryOperator 函数式接口,取两个值并产生一个新值
     * @param defaultResult  默认值或初始值。
     * @return U
     */
    public static <E, U> U sum(Collection<E> collection, Function<E, U> keyMapper, BinaryOperator<U> binaryOperator, U defaultResult) {
        if (collection == null) {
            return defaultResult;
        }
        return collection.stream().map(keyMapper).reduce(defaultResult, binaryOperator);
    }

    public static <E> E sum(Collection<E> collection, BinaryOperator<E> binaryOperator, E defaultResult) {
        return sum(collection, Function.identity(), binaryOperator, defaultResult);
    }


    public static void main(String[] args) {
        class User {
            private String name;
            private int count;
            private String date;

            private User(String name, int count, String date) {
                this.name = name;
                this.count = count;
                this.date = date;
            }

            private String getName() {
                return name;
            }

            private int getCount() {
                return count;
            }

            private String getDate() {
                return date;
            }

            @Override
            public String toString() {
                return "User{" +
                        "name='" + name + '\'' +
                        ", count=" + count +
                        ", date='" + date + '\'' +
                        '}';
            }
        }
        List<User> list = Arrays.asList(
                new User("张三", 1, "2020-12-20")
                , new User("张三", 2, "2020-12-21")

                , new User("李四", 3, "2020-12-22")
                , new User("李四", 4, "2020-12-24"),

                new User("王五", 100, "2020-12-27"));


        System.out.println(maxByGroup(list, User::getName, Comparator.comparing(User::getDate)));
        System.out.println(minByGroup(list, User::getName, Comparator.comparing(User::getDate)));
        System.out.println(sumIntegerByGroup(list, User::getName, User::getCount));

        System.out.println("======================================");
        System.out.println(maxByGroup(new ArrayList<>(), User::getName, Comparator.comparing(User::getDate)));
        System.out.println(toMap(new ArrayList<>(), User::getName));
        System.out.println(mapList(list, User::getName));
        System.out.println(mapSet(list, User::getName));

        System.out.println("=======================================");
        System.out.println(sumInteger(Arrays.asList(6, 9)));
        System.out.println(sum(list, User::getCount, Integer::sum, 0));
        System.out.println(sum(Arrays.asList(new BigDecimal(2), new BigDecimal(6)), BigDecimal::add, BigDecimal.ZERO));

    }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Java 8 提供了一系列的工具和 API 来帮助我们进行多任务并行处理。其中最常用的是 `java.util.concurrent` 包中的类,比如 `Executor`、`ExecutorService`、`ThreadPoolExecutor` 等。 举个例子,我们可以使用 `ExecutorService` 来创建一个线程池,然后将多个任务封装成 `Callable` 或 `Runnable` 接口的实现类,然后使用 `ExecutorService.submit()` 方法将任务提交到线程池中进行执行: ```java ExecutorService executorService = Executors.newFixedThreadPool(4); Future<String> result1 = executorService.submit(() -> "Task 1"); Future<String> result2 = executorService.submit(() -> "Task 2"); String result = result1.get() + " " + result2.get(); System.out.println(result); executorService.shutdown(); ``` 在这个例子中,我们创建了一个可以同时执行 4 个任务的线程池,然后提交了两个任务到线程池中执行。最后使用 `Future.get()` 方法获取任务的执行结果,并将两个结果拼接起来。 除了使用线程池以外,Java 8 还提供了一些其他的工具和 API 来帮助我们进行多任务并行处理,比如 `CompletableFuture` 和 `Stream API` 等。 ### 回答2: Java 8引入了新的特性来支持多任务并行处理。其中最常用的特性是流(Stream)和并行流(Parallel Stream)。 流(Stream)是一种功能强大的数据处理工具,它可以让我们以声明式的方式来处理集合或数组。通过使用流,我们可以通过一系列的中间操作过滤、映射或排序数据,并最终进行终端操作,例如求和或聚合。流的特点是可以自动进行数据分块处理,这样可以提高数据处理的效率。但是,普通的流只能在一个线程中进行操作,无法利用多核心处理器的优势。 为了解决这个问题,Java 8引入了并行流(Parallel Stream)这个概念。并行流可以将一个流中的元素自动分块处理,并在多个线程中同时进行处理。这样,我们就可以充分利用多核心处理器的能力,加快数据处理的速度。 使用并行流非常简单,只需要将普通的流调用parallel()方法即可将其转换为并行流。然后,在进行终端操作时,例如使用forEach()或reduce()方法,流会自动将元素分块处理分发给多个线程进行并行处理。在使用并行流时,我们需要注意线程安全的问题,确保共享的数据是可变的。 除了并行流,Java 8还引入了新的线程池框架来支持多任务并行处理。通过使用Fork/Join框架,我们可以将一个任务分解成多个子任务,并通过递归方式并行处理子任务,最后将它们的结果合并起来。这样可以更容易地在多核心处理器上实现任务的并行处理。 总之,Java 8提供了多种方式来支持并行处理,包括并行流和Fork/Join框架。通过合理地使用这些特性,我们可以充分利用多核心处理器的能力,提高程序的执行效率。 ### 回答3: Java 8引入了新的并行处理能力,使得多任务处理变得更加简单和高效。Java 8使用了Stream API来实现并行处理,这是一种能够处理大量数据的流式处理方式。 在Java 8中,我们可以使用Stream API来处理集合、数组等数据源。通过调用`parallelStream`方法,我们可以将Stream转换为并行流,从而实现并行处理。 并行处理的好处在于它可以将大量数据分成多个小块,并使用多个线程同时处理这些小块。这样可以充分利用计算资源,提高处理速度。 在并行处理中,我们可以使用`forEach`方法来对每个元素进行处理,也可以使用`map`方法来对元素进行映射。此外,我们还可以在并行处理中使用`filter`方法来过滤元素,或者使用`reduce`方法来将元素进行归约。 值得注意的是,并行处理可能会引发线程安全问题。在使用并行处理时,我们要确保共享对象的线程安全。另外,我们还要避免在并行流中执行有副作用的操作,因为这可能导致意外结果。 总之,Java 8的并行处理能力为我们提供了一种高效处理大量数据的方式。通过使用Stream API,我们可以轻松实现多任务的并行处理,并充分利用计算资源,加快程序的执行速度。然而,在使用并行处理时,我们需要注意线程安全和副作用等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值