Dapatkan Karyawan sebelum dan sesudah tanggal tertentu bergabung dari Daftar Karyawan dengan aliran Java


9

Saya harus Listdari Employees dengan tanggal bergabung berbeda. Saya ingin Mendapatkan Karyawan sebelum dan setelah tanggal tertentu bergabung dari Daftar menggunakan aliran.

saya mencoba kode berikut,

 List<Employee> employeeListAfter = employeeList.stream()
                .filter(e -> e.joiningDate.isAfter(specificDate))
                .collect(Collectors.toList());

List<Employee> employeeListBefore = employeeList.stream()
        .filter(e -> e.joiningDate.isBefore(specificDate))
        .collect(Collectors.toList());

class Employee{
    int id;
    String name;
    LocalDate joiningDate;
}

Apakah ada cara untuk melakukan ini dalam satu aliran?


1
Anda dapat menggunakanpartitioningBy
— Code_Mode

5
Sebelum dan sesudah - jadi Anda ingin semua karyawan kecuali mereka yang bergabung pada tanggal tersebut?
— John3136

Dengan asumsi bahwa "setidaknya sudah menjadi karyawan", Anda pasti ingin berpisah sebelum dan tidak sebelumnya, sama sekali tidak peduli sama sekali.
— JollyJoker

Jawaban:


16

Anda dapat menggunakan partitioningByseperti di bawah ini,

Map<Boolean, List<Employee>> listMap = employeeList.stream()
        .collect(Collectors.partitioningBy(e -> e.joiningDate.isAfter(specificDate)));

List<Employee> employeeListAfter = listMap.get(true);
List<Employee> employeeListBefore = listMap.get(false);

partisiing Dengan Mengembalikan Kolektor yang mempartisi elemen input sesuai dengan Predikat, dan mengaturnya menjadi aMap<Boolean, List<T>>

Perhatikan bahwa ini tidak akan menangani karyawan specificDate.


1
Penjelasan kode akan sangat bagus.
— Vishwa Ratna

2
Ini tidak melakukan persis apa yang dilakukan kode - karyawan dengan specificDateakan mendarat di falsepartisi, di mana dalam kode tersebut tidak ada
— Andronicus

Bagaimana cara menambahkan specificDate.plusDays(1)menyelesaikan masalah? specificDateakan tetap di falsebagian.
— Andronicus

Maka akan berada di truepartisi ...
— Andronicus

1
@Andronicus: Hanya OP yang tahu apakah perilaku ini bug atau fitur. Bagi saya, tampaknya lebih aman untuk tidak meninggalkan karyawan.
— Eric Duminil

9

Jika daftar Anda dapat memiliki entri yang bergabung padaspecificDate , maka Anda mungkin menemukan groupingByberguna:

Map<Integer, List<Employee>> result = employeeList.stream()
    .map(emp -> new AbstractMap.SimpleEntry<>(specificDate.compareTo(emp.getJoiningDate()), emp))
    .collect(Collectors.groupingBy(entry -> entry.getKey() > 0 ? 1 : (entry.getKey() < 0 ? -1 : 0),
            Collectors.mapping(entry -> entry.getValue(), Collectors.toList())));

employeeListAfter = result.get(-1);
employeeListBefore = result.get(1);
employeeListOnSpecificDate = result.get(0);

The resultpeta berisi Employeecatatan dikelompokkan berdasarkan posisi relatif untuk specificDate, sehingga Anda dapat memilih yang bergabung sebelum, sesudah, atau pada tanggal yang ditentukan.


Ini harus menjadi jawaban yang diterima
— Andronicus

2
-1. Anda membuat asumsi salah yang compareTohanya akan mengembalikan -1, 0, atau 1. Faktanya LocalDate.compareTo dapat mengembalikan int apa pun.
— MikeFHay

1
@ MikeFHay Terima kasih telah menunjukkannya. Saya melakukan tes yang sangat cepat dan melompat ke kesimpulan. Perubahan implementasi (dan tiba-tiba terlihat rumit).
— ernest_k

2
@ernest_k: Anda bisa menggunakan yang asli compareTodan memanggilnya Integer.signum.
— Eric Duminil

1
@JollyJoker Kalau-kalau Anda tidak tahu, Anda dapat menautkan ke baris tertentu di github: seperti ini . Mengklik nomor baris akan mengubah URL secara langsung. Jangan ragu untuk mengabaikan jika Anda sudah tahu atau tidak peduli. ;)
— Eric Duminil

4

Anda perlu menyaring karyawan dengan tanggal khusus ini. Kemudian Anda dapat menggunakan partisi:

Map<Boolean, List<Employee>> partitioned = employeeList.stream()
    .filter(e -> !e.joiningDate.equals(specificDate))
    .collect(partitioningBy(e -> e.joiningDate.isAfter(specificDate)));

List<Employee> employeeListAfter = partitioned.get(true);
List<Employee> employeeListBefore = partitioned.get(false);

Ini akan membuat peta koleksi berdasarkan jika mereka memenuhi predikat.


Belajar partitioningBy hari ini.
— Vishwa Ratna

Tidak, Anda tidak dapat memfilter dengan tanggal karena akan memfilter karyawan dengan hanya tanggal khusus
— Code_Mode

@ Kode_Mode oh, ya, saya melewatkannya, terima kasih!
— Andronicus

2

Anda dapat menggunakan Collectors.groupingBydan menggunakan compareTometode untuk mengelompokkan daftar karyawan berdasarkan tanggal sebelumnya, saat ini dan masa depan

Map<Integer, List<Employee>> result = employeeList.stream()
            .collect(Collectors.groupingBy(e-> e.joiningDate.compareTo(specificDate)< 0 ? -1 : (e.joiningDate.compareTo(specificDate) == 0 ? 0 : 1)));

Jadi hasilnya akan

key--> -1 ---> will have employees with previous date
key--> 0 ---> will have employees with current date
key--> 1 ---> will have employees with future date
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.