我有重复的代码,其中代码中唯一的区别是类名称及其传入的参数。 有没有办法重用这段代码?
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>
,您可以进一步简化:如果您声明 staffList
和roomList
像这样
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/