java - 我可以在类名是 java 中唯一变化的地方使用继承吗?

标签 java arrays class inheritance

我有重复的代码,其中代码中唯一的区别是类名称及其传入的参数。 有没有办法重用这段代码?

public void addToStaffList(Staff staff)
{
    if(this.staffList == null)
    {
        this.staffList = new Staff[]{staff};
        return;
    }
    if(!isThisStaffAlreadyListed(staff))
    {
        for(int i = 0; i < this.getStaffList().length; i++)
        { // first fill any empty array index
            if(this.getStaffList()[i] == null)
            {
                this.getStaffList()[i] = staff;
                return;
            }
        }
    }
    if(!isThisStaffAlreadyListed(staff))
    {
        int length = this.getStaffList().length;
        length++;
        Staff[] newStaffList = new Staff[length];
        for(int i = 0; i < this.getStaffList().length; i++)
        { // add staff to extended array with bigger index
            newStaffList[i] = this.getStaffList()[i];
        }
        newStaffList[newStaffList.length-1] = staff;
        this.staffList = newStaffList;
    }
}

这与...相同

public void addToRoomsList(Room room)
{
    if(this.roomsList == null)
    {
        this.roomsList = new Room[]{room};
        return;
    }
    if(!isThisRoomAlreadyListed(room))
    {
        for(int i = 0; i < this.getRoomsList().length; i++)
        { // first fill any empty array index
            if(this.getRoomsList()[i] == null)
            {
                this.getRoomsList()[i] = room;
                return;
            }
        }
    }
    if(!isThisRoomAlreadyListed(room))
    {
        int length = this.getRoomsList().length;
        length++;
        Room[] newRoomsList = new Room[length];
        for(int i = 0; i < this.getRoomsList().length; i++)
        { // add room to extended array with bigger index
            newRoomsList[i] = this.getRoomsList()[i];
        }
        newRoomsList[newRoomsList.length-1] = room;
        this.roomsList = newRoomsList;
    }
}

这些代码块中的唯一区别是类名“Staff”和“Room”以及参数变量“staff”和“room”。 即使在这些代码块中,也有更多重复的 block ,例如 isThisStaffAlreadyListed()isThisRoomAlreadyListed() ,它们中的代码块都是相同的,除了类名改变。 有没有办法通过某种方式传递类名称及其参数来重用此代码?

最佳答案

大部分代码都会在数组中查找空位,如果空间不足,则将数组扩展一个元素。

如果您仅限于使用数组,重用代码的一种方法是创建一个扩展数组的通用辅助方法,如下所示:

public <T> T[] fitOrExpand(T[] a, T item, Class<T> type) {
    if (a == null) {
        T[] res = (T[])Array.newInstance(type, 1);
        res[0] = item;
        return res;
    }
    for (int i = 0 ; i != a.length ; i++) {
        if (a[i] == null) {
            a[i] = item;
            return a;
        }
    }
    T[] res = (T[])Array.newInstance(type, a.length+1);
    System.arraycopy(a, 0, res, 0, a.length);
    res[res.length-1] = item;
    return res;
}

您需要导入java.lang.reflect.Array以便编译。

这几乎就是您的代码,但有三个异常(exception):

  • 假设房间或工作人员未列出。您必须单独检查,
  • 它使用泛型类型 T而不是代码中的特定类型,并且
  • 它使用 System.arraycopy 而不是第二个循环。

有了这个方法,你就可以像这样重写这两个方法:

public void addToStaffList(Staff staff) {
    if(isThisStaffAlreadyListed(staff)) return;
    this.staffList == fitOrExpand(this.staffList, staff, Staff.class);
}

public void addToRoomsList(Room room) {
    if(isThisRoomAlreadyListed(room)) return;
    this.roomsList == fitOrExpand(this.roomsList, room, Room.class);
}

如果你可以使用ArrayList<T> ,您可以进一步简化:如果您声明 staffListroomList像这样

List<Room> roomList = new ArrayList<Room>();
List<Staff> staffList = new ArrayList<Staff>();

你的辅助方法将如下所示:

static <T> void fitOrExpand(List<T> list, T item) {
    // No null checking of the entire list is necessary,
    // because we created an empty list.
    // Go straight to null-checking elements:
    for (int i = 0 ; i != list.size() ; i++) {
        if (list.get(i) == null) {
            list.put(i, item);
            return;
        }
    }
    list.add(item);
}

这两个调用将如下所示:

public void addToStaffList(Staff staff) {
    if(isThisStaffAlreadyListed(staff)) return;
    fitOrExpand(this.staffList, staff);
}

public void addToRoomsList(Room room) {
    if(isThisRoomAlreadyListed(room)) return;
    fitOrExpand(this.roomsList, room);
}

关于java - 我可以在类名是 java 中唯一变化的地方使用继承吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29193001/

相关文章:

java - 更改或覆盖 Mongorepository.save(document) 的默认行为

java - 在单个流中组合 allMatch、noneMatch 和 anyMatch

ios - 有没有办法动态实例化类类型

C++ 单例和 new 运算符

javascript - ES6 类 Promise 链——访问 'this'

Java 集合 HashTable 和 HashMap

java - 按两个字段分组,然后对 BigDecimal 求和

python - 为什么 np.nan_to_num() 不转换这个 (n x m) 数组?

c - 在 C 中释放一个 mpc_t 数组

android - 如何在 JSON 数组 Android 中解析 JSON 数组