У меня есть собственный класс Java, т.е. Сотрудник, имеющий поля ниже,
public class Employee {
private String name;
private String dept;
private Integer age;
private Double salary;
}
public Employee(String name, String dept, Integer age, Double salary) {
this.name = name;
this.dept = dept;
this.salary = salary;
this.age = age;
}
//getter and setters
Мой объект списка имеет данные ниже,
List<Employee> list = Arrays.asList(
new Employee("mahesh", "IT", 25, 1000.00),
new Employee("rajesh", "IT", 30, 1200.00),
new Employee("Saket", "IT", 30, 1000.00),
new Employee("Samuel", "IT", 30, 1150.00),
new Employee("Anil", "Eng", 29, 2000.00),
new Employee("Sachin", "Eng", 29, 2000.00));
Мне нужно перебрать этот список, и обновленный список должен вернуть первую, третью, пятую и шестую записи. сгруппируйте записи, используя отдел и зарплату, и если число группировок больше 1, эти записи должны вернуться. В приведенном выше примере второй и четвертый раз это произошло один раз в виде группировки, поэтому эти записи должны пропускаться.
Итак, окончательный список должен содержать эти записи:
List<Employee> list = Arrays.asList(
new Employee("mahesh", "IT", 25, 1000.00),
new Employee("Saket", "IT", 30, 1000.00),
new Employee("Anil", "Eng", 29, 2000.00),
new Employee("Sachin", "Eng", 29, 2000.00));
Необходимо сгруппировать на основе двух полей, то есть отдела и зарплаты, и API потока должен возвращать обновленный список.
@BasilBourque, потому что у первого и третьего один и тот же отдел, то есть «ИТ», и одинаковая зарплата, то есть 1000,00. Аналогично пятому и шестому, т. е. кафедра «Инж» и зарплата у обоих 2000,00. То, что не ясно?
@Abra Хороший вопрос явно излагает свои требования, а не заставляет меня гадать.
@BasilBourque Мне не нужно было догадываться.
вы можете попробовать следующий фрагмент кода
public static void main(String[] args) {
List<Employee> list = Arrays.asList(
new Employee("mahesh", "IT", 25, 1000.00),
new Employee("rajesh", "IT", 30, 1200.00),
new Employee("Saket", "IT", 30, 1000.00),
new Employee("Samuel", "IT", 30, 1150.00),
new Employee("Anil", "Eng", 29, 2000.00),
new Employee("Sachin", "Eng", 29, 2000.00)
);
// Group by concatenated department and salary key
Map<String, List<Employee>> groupedByDeptAndSalary = filteredList.stream()
.collect(Collectors.groupingBy(emp -> emp.getDept() + "-" + emp.getSalary()));
// Flatten the groups and retain only those with more than one element
List<Employee> result = groupedByDeptAndSalary.values().stream()
.filter(group -> group.size() > 1)
.flatMap(Collection::stream)
.collect(Collectors.toList());
result.forEach(System.out::println);
}
В этом решении:
1. сгруппируйте отфильтрованных сотрудников по отделам и зарплатам (составьте их как идентификатор).
2. Выровнять группы и отфильтровать их, чтобы сохранить только те группы, в которых более одного сотрудника.
3.соберите результаты и распечатайте их.
Это должно дать вам желаемый результат:
Employee{name='mahesh', dept='IT', age=25, salary=1000.0}
Employee{name='Saket', dept='IT', age=30, salary=1000.0}
Employee{name='Anil', dept='Eng', age=29, salary=2000.0}
Employee{name='Sachin', dept='Eng', age=29, salary=2000.0}
Насколько я понимаю, критерий 1 представлял собой описание желаемого результата, а не шаг в процессе группировки/фильтрации.
@AndrewYim, ты прав.
о, я понял, я изменю ответ
Если вас интересуют элементы, которые не являются уникальными при группировке по сочетанию отдела и зарплаты, вы можете выполнить группировку и фильтрацию на основе количества. Кроме того, для этого потребуется плоское отображение элементов обратно для структуры данных, желаемой на выходе:
List<Employee> employees = list.stream()
.collect(Collectors.groupingBy(employee -> employee.dept + employee.salary))
.entrySet()
.stream()
.filter(e -> e.getValue().size() > 1)
.flatMap(e -> e.getValue().stream())
.collect(Collectors.toList());
Примечание. Это зависит от уникальности ключа, созданного с использованием комбинации отдела и зарплаты, представленной типом String
.
это сработало, как и ожидалось.
Почему люди всегда придумывают ненадежную и неэффективную конкатенацию строк для создания составного ключа? Простое использование функции группировки employee -> Arrays.asList(employee.dept, employee.salary)
обеспечивает надежный групповой ключ. Кстати, можно сначала стримить через values()
вместо entrySet()
, тогда не надо звонить getValue()
…
«обновленный список должен возвращать первую, третью, пятую и шестую записи» — Почему? Вам нужно кое-что объяснить. Покажите ожидаемый результат и объясните, почему. Голосование за закрытие как неясное. И, скорее всего, дубликат тоже.