/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.stream.Collectors;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
	public static class Obj {
		private int value;
		private String category;
		
		public Obj(int value, String category) {
			this.value = value;
			this.category = category;
		}
		
		public int getValue() { return value; }
		public void setValue(int value) { this.value = value; }

		public String getCategory() { return category; };
		public void setCategory(String category) {this.category = category; };

        
		@Override
		public String toString() {
			return category + ":" + value;
		}
	}
	
	public static void main (String[] args) throws java.lang.Exception
	{
		List<Obj> list = new ArrayList<>();
		list.add(new Obj(500, "GROCERY"));
		list.add(new Obj(300, "GROCERY"));
		list.add(new Obj(100, "FUEL"));
		list.add(new Obj(300, "SMALL APPLIANCE REPAIR"));
		list.add(new Obj(200, "FUEL"));
		
		List<Obj> values = list.stream().collect(
        Collectors.groupingBy(Obj::getCategory, Collectors.reducing((a, b) -> new Obj(a.getValue() + b.getValue(), a.getCategory())))
    ).values().stream().map(Optional::get).collect(Collectors.toList());
		
	List<Obj> values2 = list.stream().sorted((o1, o2) -> o1.getCategory().compareTo(o2.getCategory()))
        .collect(LinkedList<Obj>::new, (ll, obj) -> {
              Obj last = null;
              if(!ll.isEmpty()) {
              	last = ll.getLast();
              }
              
              if (last == null || !last.getCategory().equals(obj.getCategory())) {
                ll.add(new Obj(obj.getValue(), obj.getCategory())); //deep copy here
              } else {
                last.setValue(last.getValue() + obj.getValue());
              }
            },
            (list1, list2) -> {
              throw new RuntimeException("parallel evaluation not supported");
            });

		
		System.out.println(values);
		System.out.println(values2);
		// your code goes here
	}
}