Reputation: 3972
I am trying to return a filtered list of rooms
by the room Class (SurgeryRoom or TechRoom). Is there a way to do it by passing the room Class in as an argument to getAvailableRooms()
instead of having the two private methods?
import java.util.*;
public class RoomBooker {
private List<IRoom> rooms = new ArrayList<>();
public RoomBooker() {
// Demo data
rooms.add(new SurgeryRoom("Surgery 1"));
rooms.add(new SurgeryRoom("Surgery 2"));
rooms.add(new TechRoom("TechRoom 1"));
rooms.add(new TechRoom("TechRoom 2"));
}
private List<IRoom> filterBySurgeryRoom() {
List<IRoom> r = new ArrayList<>();
for (IRoom room : rooms) {
if (room instanceof SurgeryRoom) {
r.add(room);
}
}
return r;
}
private List<IRoom> filterByTechRoom() {
List<IRoom> r = new ArrayList<>();
for (IRoom room : rooms) {
if (room instanceof TechRoom) {
r.add(room);
}
}
return r;
}
public List<IRoom> getAvailableRooms(String roomType, Date date) {
List<IRoom> available = new ArrayList<>();
switch (roomType.toUpperCase()) {
case "SURGERY":
available = filterBySurgeryRoom();
break;
case "TECH":
available = filterByTechRoom();
break;
}
return available;
}
}
Upvotes: 0
Views: 728
Reputation: 56413
make the method accept a Predicate
parameter i.e:
private List<IRoom> filterRoomByType(Predicate<IRoom> predicate) {
List<IRoom> r = new ArrayList<>();
for (IRoom room : rooms) {
if (predicate.test(room)) {
r.add(room);
}
}
return r;
}
so now whenever you call the method filterRoomByType
, you can pass in a function which defines the criteria for the if
condition.
filterRoomByType(e -> e instanceof SurgeryRoom);
or
filterRoomByType(e -> e instanceof TechRoom);
Upvotes: 2
Reputation: 54148
You can use Java Streams
to achieve this easily
public List<IRoom> getAvailableRooms(Class<? extends IRoom> roomType, Date date) {
return rooms.stream().filter(roomType::isInstance).collect(Collectors.toList());
}
And call with :
List<IRoom> list = getAvailableRooms(SurgeryRoom.class, new Date(1234));
List<IRoom> list = getAvailableRooms(TechRoom.class, new Date(1234));
Later when you'll add the date
filter you'd be able to use the same method just improve the filter part
Like getting all rooms for specific class AND those which date is after date in parameter :
public List<IRoom> getAvailableRooms(Class<? extends IRoom> roomType, Date date) {
return rooms.stream()
.filter(roomType::isInstance) //== .filter(r->roomType.isInstance(r))
.filter(r -> r.getDate().after(date))
.collect(Collectors.toList());
}
Upvotes: 2
Reputation: 1425
Pass in the class as an argument and use the isInstance
method documented here: https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isInstance(java.lang.Object)
private <T extends IRoom> List<T> filterRoomByType(Class<T> roomType) {
List<T> r = new ArrayList<>();
for (IRoom room : rooms) {
if (roomType.isInstance(room)) {
r.add((T) room);
}
}
return r;
}
Upvotes: 3