我是初学者,讲师告诉我减少这两个功能中的重复代码。这是一个图书馆。我想我还需要一个方法来检查数组。我需要的是我需要使用的一些建议/原则。我会自己写这个方法。谢谢! getBooks()返回存储Books的ArrayList。
public List<Book> getAvailableBooks() {
List<Book> result = new ArrayList<Book>();
for (int i = 0; i < this.getBooks().size(); i++) {
if (this.getBooks().get(i).getPerson() == null) {
result.add(this.getBooks().get(i));
}
}
return result;
}
public List<Book> getUnavailableBooks() {
List<Book> result = new ArrayList<Book>();
for (int i = 0; i < this.getBooks().size(); i++) {
if (this.getBooks().get(i).getPerson() != null) {
result.add(this.getBooks().get(i));
}
}
return result;
}
答案 0 :(得分:2)
您已经有两种方法。你不能再增加一个来减少。
但是你可以有一种方法而不是两种方法。 e.g。
public List<Book> getBooks(boolean available) {
现在您有一种方法,您可以告诉它您是否需要可用或不可用的书籍。
答案 1 :(得分:1)
传入一个应该指示
的布尔参数(this.getBooks().get(i).getPerson() == null)
应该评估,并添加条件来检查。即该表达式应该返回true还是false。
答案 2 :(得分:1)
这里有一些建议:
使用增强型for
循环而不是索引循环。这样可以避免在每种方法中使用this.getBooks().get(i)
两次。
不可用的图书+可用图书=图书总数。使用此公式可避免在这两种方法中编写所有代码。您可能希望使用Set<Book>
代替List<Book>
,以便更轻松地使用它。 [提示:设定差异]。
此外,我不会在这些方法中执行null
检查,而是仅在isAvailable()
类中添加方法Book
,这将返回{{ 1}}如果可用,则为true
。
答案 3 :(得分:1)
在一般情况下,如果您在代码中看到一个非常常见的模式,则通常有机会减少重复。第一步是查看您的代码并确定实际差异。你有:
public List<Book> getAvailableBooks() {
List<Book> result = new ArrayList<Book>();
for (int i = 0; i < this.getBooks().size(); i++) {
if (this.getBooks().get(i).getPerson() == null) {
result.add(this.getBooks().get(i));
}
}
return result;
}
public List<Book> getUnavailableBooks() {
List<Book> result = new ArrayList<Book>();
for (int i = 0; i < this.getBooks().size(); i++) {
if (this.getBooks().get(i).getPerson() != null) {
result.add(this.getBooks().get(i));
}
}
return result;
}
忽略方法名称,让我们进行逐行比较。这样做,我们可以发现差异:
if (this.getBooks().get(i).getPerson() == null) {
// vs:
if (this.getBooks().get(i).getPerson() != null) {
唯一的区别是==
与!=
;条件是倒置的。在确定差异之后,下一步是查看是否可以参数化行为,以便逻辑本身完全相同,并且仅取决于少数外部变量的值。在这种情况下,我们可以看到这样的转变:
a == x => (a == x) == true
a != x => (a == x) == false
both: => (a == x) == <variable>
所以我们可以将这两行等同起来:
boolean available = true;
if ((this.getBooks().get(i).getPerson() == null) == available) {
// vs:
boolean available = false;
if ((this.getBooks().get(i).getPerson() == null) == available) {
现在逻辑是等价的,我们只需更改available
即可在两者之间进行选择。把它作为方法参数,瞧!
public List<Book> getBooksByAvailability (bool available) {
List<Book> result = new ArrayList<Book>();
for (int i = 0; i < this.getBooks().size(); i++) {
if ((this.getBooks().get(i).getPerson() == null) == available) {
result.add(this.getBooks().get(i));
}
}
return result;
}
请注意,解决此问题的另一种方法是使“可用性”本身成为图书的属性。例如,如果将可用性测试移动到新方法Book.isAvailable()
,则解决方案会变得更加明显:
public List<Book> getBooksByAvailability (bool available) {
List<Book> result = new ArrayList<Book>();
for (int i = 0; i < this.getBooks().size(); i++) {
if (this.getBooks().get(i).isAvailable() == available) {
result.add(this.getBooks().get(i));
}
}
return result;
}
这还有一个额外的好处,就是让你在不修改其他任何地方的代码的情况下改变“可用性”的内部定义(例如,如果将来你认为getPerson() == null
不足以说明“可用性” ,你只需要在Book.isAvailable()
)中更改它。
至于清晰度,你可以像Rohit Jain在this answer中提到的那样,切换到增强的for
循环以提高可读性,例如:
public List<Book> getBooksByAvailability (bool available) {
List<Book> result = new ArrayList<Book>();
for (Book book : this.getBooks()) {
if (book.isAvailable() == available) {
result.add(book);
}
}
return result;
}
要保留两个现有功能,如果有必要,您可以使用类似上面的内容作为私有效用方法,由两个公共方法调用。
答案 4 :(得分:0)
如果您不想更改方法签名,我认为您不能比现有的更好。您可以将循环重写为foreach,并可能执行列表的替换。肮脏的解决方案,但讲师可能会接受它。
public List<Book> getAvailableBooks() {
Set<Book> result = new HashSet<>(getBooks());
result.removeAll(getUnavailableBooks());
return new ArrayList<Book>(result);
}
public List<Book> getUnavailableBooks() {
List<Book> result = new ArrayList<Book>();
for (Book b: getBooks()) {
if (b.getPerson() != null) {
result.add(b);
}
}
return result;
}
可能不是最快的解决方案,但很短暂