Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum values in two arrays lists and return a third list

Tags:

java

Create a third array list by summing up data related to same element if present in both lists, else insert the new data

I created two maps from the two array lists with Id as key and then created a set by combining keys from both maps. Making use of the values in set, i queried both the lists and arrived at the sum. I am seeing the expected output if i follow this method, but wanted to know if there is any other efficient way of achieving this in Java 1.6

----------------Java----------------

public class Stock {

    private int stockCode;
    private int stockQuantity;
    private int stockValue;

    public int getStockCode() {
        return stockCode;
    }

    public int getStockQuantity() {
        return stockQuantity;
    }

    public int getStockValue() {
        return stockValue;
    }

    public Stock(int stockCode, int stockQuantity, int stockValue) {
        this.stockCode = stockCode;
        this.stockQuantity = stockQuantity;
        this.stockValue = stockValue;
    }

    public static void main(String[] args){
        List<Stock> oldStock = new ArrayList<Stock>();
        Stock s1 = new Stock(1,  20, 16000);
        Stock s2 = new Stock(2, 10, 5000);
        Stock s3 = new Stock(3,  15, 3000);
        oldStock.add(s1);
        oldStock.add(s2);
        oldStock.add(s3);

        List<Stock> newStock = new ArrayList<Stock>();
        Stock s4 = new Stock(5, 5, 2500);
        Stock s5 = new Stock(1, 10, 8000);
        Stock s6 = new Stock(3, 10, 2000);
        newStock.add(s4);
        newStock.add(s5);
        newStock.add(s6);

        List<Stock> netStock = new ArrayList<Stock>();

        Map<Integer, Stock> oldStockMap = new HashMap<Integer, Stock>();
        for(Stock os:oldStock){
            oldStockMap.put(os.getStockCode(),os);
        }
        Map<Integer, Stock> newStockMap = new HashMap<Integer, Stock>();
        for(Stock ns:newStock){
            newStockMap.put(ns.getStockCode(),ns);
        }
        Set<Integer> keySet = new HashSet<Integer>();
        keySet.addAll(oldStockMap.keySet());
        keySet.addAll(newStockMap.keySet());

        for(Integer ks:keySet){
            Integer netStockQ=0;
            Integer netStockV=0;
            if(oldStockMap.get(ks)!=null && newStockMap.get(ks)!=null) {
                netStockQ =oldStockMap.get(ks).getStockQuantity() + newStockMap.get(ks).getStockQuantity();
                netStockV = oldStockMap.get(ks).getStockValue() + newStockMap.get(ks).getStockValue();
            } else if(oldStockMap.get(ks)==null && newStockMap.get(ks)!=null){
                netStockQ = newStockMap.get(ks).getStockQuantity();
                netStockV = newStockMap.get(ks).getStockValue();
            } else if(oldStockMap.get(ks)!=null && newStockMap.get(ks)==null){
                netStockQ =oldStockMap.get(ks).getStockQuantity();
                netStockV = oldStockMap.get(ks).getStockValue();
            }
            netStock.add(new Stock(ks,netStockQ, netStockV));
        }

        for(Stock ns: netStock){
            System.out.println(ns.getStockCode() +"- Quantity - "+ ns.getStockQuantity()+"- Value -"+ns.getStockValue());
        }
    }
}

---------------Output---------------

1- Quantity - 30- Value -24000
2- Quantity - 10- Value -5000
3- Quantity - 25- Value -5000
5- Quantity - 5- Value -2500
like image 687
GVR Avatar asked Sep 12 '19 04:09

GVR


3 Answers

You can do the following (given that you cannot upgrade to Java 8)

  • Create a Map with stock code as key and stock as the value
Map<Integer, Stock> netStockMap = new HashMap<Integer, Stock>();
  • Then add all the old stock entries to that map as follows.
for (Stock oldStockItem: oldStock) {
    netStockMap.put(oldStockItem.getStockCode(), oldStockItem);
}
  • Then for each new stock entry, check if an old entry exists in the map. If exists, create a new stock entry combining both old and new entry. Otherwise just add the new stock entry to the map.
for (Stock newStockItem: newStock) {
    Integer stockCode = newStockItem.getStockCode();
    Stock oldStockItem = netStockMap.get(stockCode);
    if (oldStockItem != null) {
        Stock netStockItem = new Stock(stockCode, oldStockItem.getStockQuantity() + newStockItem.getStockQuantity(),oldStockItem.getStockValue() + newStockItem.getStockValue());
        netStockMap.put(stockCode, netStockItem);

    } else {
        netStockMap.put(stockCode, newStockItem);
    }
}
  • Then get the values of the map as the final stock list
List<Stock> netStock = new ArrayList<Stock>(netStockMap.values());
like image 171
Udith Gunaratna Avatar answered Oct 12 '22 13:10

Udith Gunaratna


If you can upgrade to Java 8, then you can efficiently achieve it through Streams.

You can use Streams to group these items based on ID and then sum their values and finally collect them as a list like:

List<Stock> netStock = new ArrayList<Stock>(oldStock);
netStock.addAll(newStock);

netStock = new ArrayList<>(netStock.stream().collect(
        Collectors.toMap(Stock::getStockCode, Function.identity(), (Stock i1, Stock i2) -> {
            i1.setStockQuantity(i1.getStockQuantity()+i2.getStockQuantity());
            i1.setStockValue(i1.getStockValue()+i2.getStockValue());
            return i1;
        })).values());

Output:

1- Quantity - 30- Value -24000
2- Quantity - 10- Value -5000
3- Quantity - 25- Value -5000
5- Quantity - 5- Value -2500

Also you need to create setter methods for your fields in Stock class

like image 36
Mustahsan Avatar answered Oct 12 '22 14:10

Mustahsan


I think that you don't need to use the 2 maps you're using (oldStockMap and newStockMap). You can use only one map, at first insert all the elements from one list, and later update elements that are repeated in second list or add elements that are not reapeated in second list. The complexity is the same, but with a little factor improvement.

public class Stock {

    private int stockCode;
    private int stockQuantity;
    private int stockValue;

    public int getStockCode() {
        return stockCode;
    }

    public int getStockQuantity() {
        return stockQuantity;
    }

    public int getStockValue() {
        return stockValue;
    }

    public Stock(int stockCode, int stockQuantity, int stockValue) {
        this.stockCode = stockCode;
        this.stockQuantity = stockQuantity;
        this.stockValue = stockValue;
    }

    public static void main(String[] args){
        List<Stock> oldStock = new ArrayList<Stock>();
        Stock s1 = new Stock(1,  20, 16000);
        Stock s2 = new Stock(2, 10, 5000);
        Stock s3 = new Stock(3,  15, 3000);
        oldStock.add(s1);
        oldStock.add(s2);
        oldStock.add(s3);

        List<Stock> newStock = new ArrayList<Stock>();
        Stock s4 = new Stock(5, 5, 2500);
        Stock s5 = new Stock(1, 10, 8000);
        Stock s6 = new Stock(3, 10, 2000);
        newStock.add(s4);
        newStock.add(s5);
        newStock.add(s6);

        Map<Integer, Stock> netStockMap = new HashMap<Integer, Stock>();

        for(Stock os:oldStock){
            netStockMap.put(os.getStockCode(),os);
        }

        for(Stock ns:newStock){
            Integer code = ns.getStockCode();
            if(netStockMap.get(ns.getStockCode()) != null) {
                Integer netStockQ = netStockMap.get(code).getStockQuantity() + ns.getStockQuantity();
                Integer netStockV = netStockMap.get(code).getStockValue() + ns.getStockValue();
                netStockMap.put(code, new Stock(code, netStockQ, netStockV));
            } else {
                netStockMap.put(code,ns);
            }
        }

        List<Stock> netStock = new ArrayList<Stock>();
        netStock.addAll(netStockMap.values());

        for(Stock ns: netStock){
            System.out.println(ns.getStockCode() +"- Quantity - "+ ns.getStockQuantity()+"- Value -"+ns.getStockValue());
        }
    }
}
like image 2
Eduardo Pascual Aseff Avatar answered Oct 12 '22 13:10

Eduardo Pascual Aseff