加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

JAVA中列表上的聚合函数

发布时间:2020-12-15 04:16:51 所属栏目:Java 来源:网络整理
导读:我有一个 Java对象列表,我需要减少它应用聚合函数,如通过数据库选择. 注意:数据是从多个数据库和服务调用计算的.我希望有数千行,每行总是会有相同数量的“单元格”.此数量在执行之间变化. 样品: 假设我的数据在对象列表[3](列表 Object [])中表示,我的数据
我有一个 Java对象列表,我需要减少它应用聚合函数,如通过数据库选择.

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

样品:

假设我的数据在对象列表[3](列表< Object []>)中表示,我的数据可能是:

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

样本1:

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

[{"A",3}]

样本2:

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

[{"A",2}]

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

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

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

解决方法

如果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",1),Arrays.<Object>asList("A",5),Arrays.<Object>asList("B",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,1],2]],[A,Y]=[[A,Y,5]]}

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

{[A,X]=Optional[[A,X]=Optional[[B,Y]=Optional[[A,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",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,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,Integer> sum(Collection<V> items,K> groupFunction,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> max(Collection<V> items,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,5]],2]]}

{[A,Y]=5,X]=3}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读