将类类型传递给过滤函数

时间:2017-11-12 18:17:22

标签: java

我正在尝试通过会议室Class(SurgeryRoom或TechRoom)返回rooms的过滤列表。有没有办法通过将房间Class作为参数传递给getAvailableRooms(),而不是使用两个私有方法?

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;
    }
}

3 个答案:

答案 0 :(得分:3)

将该类作为参数传递,并使用此处记录的isInstance方法: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;
}

答案 1 :(得分:2)

使方法接受Predicate参数,即:

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;
}

所以现在每当你调用方法filterRoomByType时,你都可以传入一个定义if条件标准的函数。

filterRoomByType(e -> e instanceof SurgeryRoom);

filterRoomByType(e -> e instanceof TechRoom);

答案 2 :(得分:2)

您可以使用Java Streams轻松实现此目标

public List<IRoom> getAvailableRooms(Class<? extends IRoom> roomType, Date date) {
    return rooms.stream().filter(roomType::isInstance).collect(Collectors.toList());
}

并致电:

List<IRoom> list = getAvailableRooms(SurgeryRoom.class, new Date(1234));
List<IRoom> list = getAvailableRooms(TechRoom.class, new Date(1234));

稍后当您添加date过滤器时,您可以使用相同的方法,只需改进filter part

比如获取特定班级的所有房间以及日期在参数之后的日期:

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());
}