Group object by field name using java 8

Find out how java 8 provided native support for grouping object by attribute

Getting started

The growth of micro services may lead you to make a series of asynchronous requests where you may want to logically group objects by identifier. Whether you are on a web screen, working in big data or making a batch of asynchronous requests it is handy to be able to group java objects by a specific criteria within java code. Lets find out how group objects within java 8 just like you do with SQL.

Set up

We will generate a project within eclipse and a class called GroupingByField. Next we will create a Stock class which will be a basis for our illustration. Note, stock actions can get complicated so we picked three use cases to begin to show off the power of java 8 grouping API. First using junit's set up method we will see a series of stock transactions from the base Stock class.

class Stock {

    String symbol;
    String sold;
    Integer shares;

    //..
}

private List<Stock> stock;

@Before
public void setUp() {

    stock = new ArrayList<>();
    stock.add(new Stock("GOOGL", "N", 10));
    stock.add(new Stock("AAPL", "N", 5));
    stock.add(new Stock("YHOO", "N", 3));
    stock.add(new Stock("AAPL", "N", 9));
    stock.add(new Stock("GOOGL", "Y", 2));
    stock.add(new Stock("GOOGL", "Y", 5));
}

Group stock by symbol

When you log into online broker website one view might be the total number of transactions based on ticker symbol. Looking at our seed data, we have performed 3 transactions with Google stock, one is still held while the others have been sold. If you have a large number of transactions you would want to view transaction history base on ticker symbol. To show the view will first call the stream method on an arraylist then the .collect method passing in a grouping function. The grouping function accepts an element that represents the key of the object to perform the groupby on. The return type is a Map where the key is stock symbols and the value is a list of Stock elements.

Let's run the example to see the output.

@Test
public void group_by_symbol_total_shares() {

    Map<String, List<Stock>> stockBySymbol = stock.stream().collect(
            Collectors.groupingBy(Stock::getSymbol));

    System.out.println(stockBySymbol);

}

Output

{GOOGL=[Stock [symbol=GOOGL, sold=N, shares=10], Stock [symbol=GOOGL,
sold=Y, shares=2], Stock [symbol=GOOGL, sold=Y, shares=5]],
AAPL=[Stock [symbol=AAPL, sold=N, shares=5], Stock [symbol=AAPL,
sold=N, shares=9]], YHOO=[Stock [symbol=YHOO, sold=N, shares=3]]}

Total traded shares

At a summary level you may want to know total number of shares traded of a particular stock. We can clone our previous example and pass in reduction collector to count the total number of shares of a particular stock.

Let's run our example to see the results.

@Test
public void group_by_symbol_traded() {

    Map<String, Integer> stockBySymbol = stock.stream().collect(
            Collectors.groupingBy(Stock::getSymbol,
                    Collectors.summingInt(Stock::getShares)));

    System.out.println(stockBySymbol);
}

Output

{GOOGL=17, AAPL=14, YHOO=3}

Outstanding shares

To find out your account balance you need to find total number of outstanding shares. To do this we will build on top of the total shares traded example. Before we perform the group by we will remove sold transactions from the list then when perform the grouping it will only contain active stocks.

Lets run our example to see the results.

@Test
public void group_by_symbol_outstanding() {

    Map<String, Integer> stockBySymbol = stock.stream()
            .filter(stock -> stock.getSold().equals("N"))
            .collect(
            Collectors.groupingBy(Stock::getSymbol,
                    Collectors.summingInt(Stock::getShares)));

    System.out.println(stockBySymbol);
}

Output

{GOOGL=10, AAPL=14, YHOO=3}

There are a lot of ways java groupingBy mimics SQLs ability with many possibilities. For instance, if we included a share price you could group by symbol and multiply to get total account values. The list could go on to group objects by attributes into business meaning. Thanks for joining in today's level up, have a great day!