2016-10-27 3 views
-1

У меня есть этот 2 объекта:Преобразовать объект Java 8 потока

public class Service { 
    private String cod; 
    private String name; 
    private String table; 
    private String selo; 
    private BigDecimal value; 
    private BigDecimal desconto; 
    private BigDecimal baseCalculo; 
    private Integer amountExcedente; 
    private String descontoLei; 

... G and S 
} 

И

public class ServiceResumo { 
     private String name; 
     private int amount; 
     private BigDecimal value; 
     private String acao; 

     public ServiceResumo(String name, BigDecimal value, int amount) { 
      this.name = name; 
      this.value = value; 
      this.amount = amount; 
     } 
    ...G and S 
    } 

Так у меня есть много услуг,

List<Service> servicos = new ArrayList<Service>(); 
servicos.add(new Service("Service A", 3,.....)); //Service A -> Name and 3 -> value 
servicos.add(new Service("Service B", 4.....)); 
servicos.add(new Service("Service A", 2,.....)); 
servicos.add(new Service("Service C", 3,.....)); 
servicos.add(new Service("Service D", 5,.....)); 
servicos.add(new Service("Service A", 6,.....)); 
servicos.add(new Service("Service A", 8,.....)); 
servicos.add(new Service("Service B", 9, .....)); 

Так можно с помощью потока в java 8 уменьшите это до списка ServiceResumo? somethign вот так:

| имя | стоимость | количество |

Служба A | 21 | 4 |

Обслуживание B | 13 | 2 |

Обслуживание C | 3 | 1 |

Служба D | 5 | 1 |

+0

Подсказка: в будущем попробуйте написать свои программы, используя английские слова, их легче понять другим! –

+0

Простите за мой неправильный ответ раньше. Если вы хотите сгруппировать «Servico», вы должны указать, что в вашем вопросе (пожалуйста, отредактируйте вопрос, если да)! –

+0

без проблем, я перехожу на английский, а точнее: D –

ответ

2

Вы получаете желаемый результат путем объединения трех коллекторов

  • Там есть встроенный коллектор, groupingBy, что позволяет сгруппировать элементы по свойству, как имя.
  • Чтобы собрать группы в объект ServicoResumo, вам понадобится сборщик, способный агрегировать экземпляры Service в такой экземпляр ServicoResumo. Для этого вам нужно создать пользовательский сборщик.
  • Поскольку результат объединения groupingBy коллектор с пользовательского коллектора будет Map<PropertyType,AggregationResult>, т.е. Map<String,ServicoResumo>, вам нужно сделать шаг после обработки, чтобы преобразовать его в List<ServicoResumo>, что может быть сделано с помощью collectingAndThen
List<ServiceResumo> result=servicos.stream() 
    .collect(Collectors.collectingAndThen(
     Collectors.groupingBy(Service::getName, 
      Collector.of(()->new ServiceResumo(null, BigDecimal.ZERO, 0), 
       (r,s) -> { 
        r.setName(s.getName()); 
        r.setValue(r.getValue().add(s.getValue())); 
        r.setAmount(r.getAmount()+1); 
       }, 
       (r1,r2) -> { 
        r1.setValue(r1.getValue().add(r2.getValue())); 
        r1.setAmount(r1.getAmount()+r2.getAmount()); 
        return r1; 
       })), 
      m -> new ArrayList<>(m.values()) 
    )); 

Первый аргумент groupingBy, Service::getName определяет свойство, которое составляет критерии группировки. Второй аргумент collectingAndThen, m -> new ArrayList<>(m.values()), рассказывает, как преобразовать Map в желаемый List.

Большая часть промежуточный, это пользовательский коллекционер, созданный с помощью Collector.of. Обратитесь к Collector documentation или “Mutable Reduction” section of the package documentation, чтобы узнать, как работают коллекторы.

Смежные вопросы