JAVA中列表上的聚合函数

 小樣兒靠邊詀_853 发布于 2023-02-04 19:57

我有一个Java对象列表,我需要减少它应用聚合函数,如通过数据库选择.

注意:数据是从多个数据库和服务调用计算的.我希望有数千行,每行总是会有相同数量的"单元格".此数量在执行之间变化.

样品:

假设我的数据ListObject[3](List)表示,我的数据可能是:

[{"A", "X", 1},
{"A", "Y", 5},
{"B", "X", 1},
{"B", "X", 2}]

样本1:

SUM索引2,按索引0和1分组

[{"A", "X", 1},
{"A", "Y", 5},
{"B", "X", 3}]

样本2:

MAX超过索引2,按索引0分组

[{"A", "Y", 5},
{"B", "X", 2}]

有人知道一些可以在Java中模拟这种行为的框架或api吗?

我的第一个选择是在NO-SQL数据库(如Couchbase)中插入所有数据,然后应用Map-Reduce,最后得到结果.但是这个解决方案有很大的开销.

我的第二个选择是嵌入一个Groovy脚本,但它也有很大的开销.

1 个回答
  • 如果Java 8是一个选项,那么你可以通过Stream.collect实现你想要的.

    例如:

    import static java.util.stream.Collectors.*;
    
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Optional;
    import java.util.Set;
    
    public class Example
    {
      public static void main(String[] args)
      {
        List<List<Object>> list = Arrays.asList(
          Arrays.<Object>asList("A", "X", 1),
          Arrays.<Object>asList("A", "Y", 5),
          Arrays.<Object>asList("B", "X", 1),
          Arrays.<Object>asList("B", "X", 2)
        );
    
        Map<Set<Object>, List<List<Object>>> groups = list.stream()
        .collect(groupingBy(Example::newGroup));
    
        System.out.println(groups);
    
        Map<Set<Object>, Integer> sums = list.stream()
        .collect(groupingBy(Example::newGroup, summingInt(Example::getInt)));
    
        System.out.println(sums);
    
        Map<Set<Object>, Optional<List<Object>>> max = list.stream()
        .collect(groupingBy(Example::newGroup, maxBy(Example::compare)));
    
        System.out.println(max);
      }
    
      private static Set<Object> newGroup(List<Object> item)
      {
        return new HashSet<>(Arrays.asList(item.get(0), item.get(1)));
      }
    
      private static Integer getInt(List<Object> items)
      {
        return (Integer)items.get(2);
      }
    
      private static int compare(List<Object> items1, List<Object> items2)
      {
        return (((Integer)items1.get(2)) - ((Integer)items2.get(2)));
      }
    }
    

    给出以下输出:

    {[A, X]=[[A, X, 1]], [B, X]=[[B, X, 1], [B, X, 2]], [A, Y]=[[A, Y, 5]]}
    
    {[A, X]=1, [B, X]=3, [A, Y]=5}
    
    {[A, X]=Optional[[A, X, 1]], [B, X]=Optional[[B, X, 2]], [A, Y]=Optional[[A, Y, 5]]}
    

    或者,使用Java 8示例作为灵感,虽然更冗长,但您可以在旧版本的Java中实现相同的功能:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class Example
    {
      public static void main(String[] args)
      {
        List<List<Object>> list = Arrays.asList(
          Arrays.<Object>asList("A", "X", 1),
          Arrays.<Object>asList("A", "Y", 5),
          Arrays.<Object>asList("B", "X", 1),
          Arrays.<Object>asList("B", "X", 2)
        );
    
        Function<List<Object>, Set<Object>> groupBy = new Function<List<Object>, Set<Object>>()
        {
          @Override
          public Set<Object> apply(List<Object> item)
          {
            return new HashSet<>(Arrays.asList(item.get(0), item.get(1)));
          }
        };
    
        Map<Set<Object>, List<List<Object>>> groups = group(
          list,
          groupBy
        );
    
        System.out.println(groups);
    
        Map<Set<Object>, Integer> sums = sum(
          list,
          groupBy,
          new Function<List<Object>, Integer>()
          {
            @Override
            public Integer apply(List<Object> item)
            {
              return (Integer)item.get(2);
            }
          }
        );
    
        System.out.println(sums);
    
        Map<Set<Object>, List<Object>> max = max(
          list,
          groupBy,
          new Comparator<List<Object>>()
          {
            @Override
            public int compare(List<Object> items1, List<Object> items2)
            {
              return (((Integer)items1.get(2)) - ((Integer)items2.get(2)));
            }
          }
        );
    
        System.out.println(max);
    
      }
    
      public static <K, V> Map<K, List<V>> group(Collection<V> items, Function<V, K> groupFunction)
      {
        Map<K, List<V>> groupedItems = new HashMap<>();
    
        for (V item : items)
        {
          K key = groupFunction.apply(item);
    
          List<V> itemGroup = groupedItems.get(key);
          if (itemGroup == null)
          {
            itemGroup = new ArrayList<>();
            groupedItems.put(key, itemGroup);
          }
    
          itemGroup.add(item);
        }
    
        return groupedItems;
      }
    
      public static <K, V> Map<K, Integer> sum(Collection<V> items, Function<V, K> groupFunction, Function<V, Integer> intGetter)
      {
        Map<K, Integer> sums = new HashMap<>();
    
        for (V item : items)
        {
          K key = groupFunction.apply(item);
          Integer sum = sums.get(key);
    
          sums.put(key, sum != null ? sum + intGetter.apply(item) : intGetter.apply(item));
        }
    
        return sums;
      }
    
      public static <K, V> Map<K, V> max(Collection<V> items, Function<V, K> groupFunction, Comparator<V> comparator)
      {
        Map<K, V> maximums = new HashMap<>();
    
        for (V item : items)
        {
          K key = groupFunction.apply(item);
          V maximum = maximums.get(key);
    
          if (maximum == null || comparator.compare(maximum, item) < 0)
          {
            maximums.put(key, item);
          }
        }
    
        return maximums;
      }
    
      private static interface Function<T, R>
      {
        public R apply(T value);
      }
    }
    

    给出以下输出:

    {[A, X]=[[A, X, 1]], [A, Y]=[[A, Y, 5]], [B, X]=[[B, X, 1], [B, X, 2]]}
    
    {[A, X]=1, [A, Y]=5, [B, X]=3}
    
    {[A, X]=[A, X, 1], [A, Y]=[A, Y, 5], [B, X]=[B, X, 2]}   
    

    2023-02-04 19:59 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有