В Java 8, если карта имеет повторяющиеся значения, получая исключение повторяющихся значений - PullRequest
0 голосов
/ 22 мая 2018

Код генерирует IllegalStateException: Duplicate key, если в списке есть повторяющиеся значения и мы пытаемся извлечь карту из списка, используя потоки Java.Если мы определим функцию слияния в методе сбора, тогда проблема будет решена.

List<Employee> empList = new ArrayList<Employee>();
Employee e1 = new Employee(1,"aaaa","mgr",100666.99);
Employee e2 = new Employee(2,"bbbb","lead",90675.99);
Employee e3 = new Employee(3,"cccc","dev",77555.99);
Employee e4 = new Employee(4,"dddd","qe",63546.99);
Employee e5 = new Employee(5,"eeee","lead",90675.99);
Employee e6 = new Employee(6,"ffff","lead",90675.99);
Employee e7 = new Employee(7,"gggg","dev",90675.99);
Employee e8 = new Employee(8,"hhhh","qe",90675.99);
empList.add(e1);
empList.add(e2);
empList.add(e3);
empList.add(e4);
empList.add(e5);
empList.add(e6);
empList.add(e7);
empList.add(e8);

List<Department> deptList = new ArrayList<Department>();
Department d1 = new Department(1, "IT", 10);
Department d2 = new Department(2, "Sales", 20);
Department d3 = new Department(3, "HR", 30);
Department d4 = new Department(4, "Support", 40);
deptList.add(d1);
deptList.add(d2);
deptList.add(d3);
deptList.add(d4);

System.out.println("\n\n List of Leads Names :");

List<String> empNames = empList.stream().filter(emp -> "lead".equals(emp.job)).map(Employee::getName).collect(Collectors.toList());
empNames.forEach(System.out::println);

Map<String,Double> jobSalMap = empList.stream().filter(emp -> "lead".equals(emp.job)).collect(Collectors.toMap(emp->emp.job,emp->emp.sal));

jobSalMap.forEach(new BiConsumer<String,Double>(){

    @Override
    public void accept(String arg0, Double arg1) {
        System.out.println(arg0 + " " + arg1);

    }

});

double sumOfLeadSal = empList.stream().filter(emp -> "lead".equals(emp.job)).mapToDouble(Employee::getSal).sum();

System.out.println(sumOfLeadSal);

Вывод:

List of Leads Names :
bbbb
eeee
ffff
    Exception in thread "main" java.lang.IllegalStateException: Duplicate key 90675.99
    at java.util.stream.Collectors.lambda$throwingMerger$0(Unknown Source)
    at java.util.HashMap.merge(Unknown Source)
    at java.util.stream.Collectors.lambda$toMap$58(Unknown Source)
    at java.util.stream.ReduceOps$3ReducingSink.accept(Unknown Source)
    at java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
    at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
    at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
    at java.util.stream.ReferencePipeline.collect(Unknown Source)
    at com.zzar.practice.TestEmployee.main(TestEmployee.java:59)

1 Ответ

0 голосов
/ 24 мая 2018

Первое решение: вам нужно знать постоянную зарплату по названию должности - без суммы.

Вы можете использовать функцию toMap с оператором слияния:

Map<String, Double> mapByJob = empList.stream()
                .collect(Collectors.toMap(Employee::getJob, Employee::getSal, (sal1, sal2) -> sal1));

mapByJob .forEach((job, sal) -> System.out.println(job + " -> " + sal));

Будет выведен вывод:

вывод -> 90675,99

Примечание:

  • Employee :: getJob 'эквивалентен'ваш emp-> emp.job
  • Но поскольку зарплата не постоянна, я бы не использовал это решение (см. второе решение).

Второе решение: вынужно знать зарплату по должности - с суммой

Суммируя зарплату по должности, вы получаете очень полезную информацию:

Map<String, Double> mapByJob = empList.stream()
                .collect(Collectors.toMap(Employee::getJob, Employee::getSal, (sal1, sal2) -> sal1+sal2));

mapByJob .forEach((job, sal) -> System.out.println(job + " -> " + sal));

В результате получается следующее:

qe -> 154222,98

dev -> 168231,98

mgr -> 100666,99

свинец -> 272027,97000000003

Java Doc: Сборщик

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...