Aggregate function on list in Java

I have a list of Java objects and I need to reduce it to apply aggregate functions, such as through database selection

Note: data is calculated from multiple databases and service calls I want thousands of rows, and each row will always have the same number of "cells" This quantity varies between executions

Sample:

Assuming that my data is represented in the object list [3] (list < object [] >), my data may be:

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

Sample 1:

Sum index 2, grouped by indexes 0 and 1

[{"A",3}]

Sample 2:

Max exceeds index 2, grouped by index 0

[{"A",2}]

Does anyone know any frameworks or APIs that can simulate this behavior in Java?

My first choice is to insert all data into no SQL database (such as couchbase), then apply map reduce, and finally get the results But this solution has a lot of overhead

My second option is to embed a groovy script, but it also has a lot of overhead

Solution

If Java 8 is an option, you can use stream Collect to achieve what you want

For example:

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)));
  }
}

The following outputs are given:

{[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]]}

Alternatively, using the Java 8 example as inspiration, although it is more lengthy, you can implement the same functions in the old version of 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);
  }
}

The following outputs are given:

{[A,5]],2]]}

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

{[A,X]=[A,Y]=[A,5],X]=[B,2]}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>