我正在尝试使用两个不同的人阅读并比较它们的两本书。如果第一个列表中的Book(它是由String标题和String作者组成的构造函数)等于另一个列表中的一本书,那么我将它添加到commonBooks列表中。这是我到目前为止所得到的,但我一直得到这个建议:"添加return语句"或"改为无效"
这是我到目前为止所拥有的:
public static ArrayList<Book> commonBooks(Person a, Person b) {
ArrayList<Book> personA = a.getRead();
ArrayList<Book> personB = b.getRead();
ArrayList<Book> sameBooks = new ArrayList<Book>();
if (personA.size() < personB.size()) {
for (int i = 0; i < personA.size(); i++) {
Book ndx = personA.get(i);
if (personB.contains(ndx)) {
sameBooks.add(ndx);
} else if (personB.size() < personA.size()) {
for (int i1 = 0; i1 < personB.size(); i1++) {
Book ndx1 = personB.get(i1);
if (personB.contains(ndx1)) {
sameBooks.add(ndx1);
} else if (personB.size() < personA.size()) {
for (int i2 = 0; i1 < personB.size(); i2++) {
Book ndx2 = personB.get(i2);
if (personB.contains(ndx2)) {
sameBooks.add(ndx2);
}
}
} else {
return sameBooks;
}
}
}
}
} else {
return sameBooks;
}
}
答案 0 :(得分:1)
这是我到目前为止所得到的,但我不断得到这个建议:&#34;添加 退货声明&#34;或&#34;改为无效&#34;
并非方法中的所有逻辑流都在方法签名中返回指定的返回类型(ArrayList<Book>
)。在if
语句中,有一些流程需要更正才能返回。
public static ArrayList<Book> commonBooks(Person a, Person b) {
ArrayList<Book> personA = a.getRead();
ArrayList<Book> personB = b.getRead();
ArrayList<Book> sameBooks = new ArrayList<Book>();
if (personA.size() < personB.size()) {
for (int i = 0; i < personA.size(); i++) {
Book ndx = personA.get(i);
if (personB.contains(ndx)) {
sameBooks.add(ndx);
} else if (personB.size() < personA.size()) {
for (int i1 = 0; i1 < personB.size(); i1++) {
Book ndx1 = personB.get(i1);
if (personB.contains(ndx1)) {
sameBooks.add(ndx1);
} else if (personB.size() < personA.size()) {
for (int i2 = 0; i1 < personB.size(); i2++) {
Book ndx2 = personB.get(i2);
if (personB.contains(ndx2)) {
sameBooks.add(ndx2);
}
}
} else {
//return sameBooks;
break;
}
}
}
}
}
return sameBooks;
}
答案 1 :(得分:1)
如果您的方法声明返回ArrayList
,那么代码中的所有可能路径都必须返回ArrayList
。 VHS的answer正确地指出了一个修正:只在一个地方退出,返回ArrayList
,并且所有路径都必须通过。
另一个超出原始问题的修复方法是使用更简单的代码:
HashSet<Book> readByA = new HashSet<>(a.getRead());
readByA.retainAll(b.getRead()); // remove all books that b has not read
return new ArrayList<>(readByA);
使用HashSet
要求您在equals()
课程中实施Book
和hashCode()
方法。许多IDE将提供为您实现它们。另一方面,对于大量的书籍,这将比你当前的代码快得多。
原始代码也至少有一个主要错误,因为如果personA.size() >= personB.size()
它返回一个空列表。因此,例如,给定两个相同的列表,它目前不会返回任何书籍,因为两者都是共同的!。
再次重写,这次没有套装:
ArrayList<Book> readByB = b.getRead();
ArrayList<Book> sameBooks = new ArrayList<Book>();
for (Book b : a.getRead()) {
if (readByB.contains(b)) sameBooks.add(b);
}
return sameBooks;
请注意,在所有条件相同的情况下,较短的代码比较长的代码片段更易于阅读和理解。这是一个更喜欢的理由......
for (Book b : a.getRead()) {
...到......
ArrayList<Book> readByA = a.getRead();
// ...
for (int i = 0; i < readByA.size(); i++) {
Book b = readByA.get(i);
...你保存了2行(66%!),不再被2个辅助变量i
和readByA
混淆了,这些变量不再是真正需要的了。
答案 2 :(得分:0)
您的方法的返回类型为ArrayList
。您已在各种条件块中添加了return语句,但是您没有在commonBooks
方法的右括号之前的所有条件块之外添加return语句。
您需要在方法的右括号之前的所有ArrayList
或else
块之外返回if
。
else {
return sameBooks;
}
//add return statement here
} //closing parenthesis of commonBooks method
答案 3 :(得分:0)
你是在思考这个!
假设您有一个集合[a, b, c]
和另一个集合[b, c, d]
。
您只需迭代一个集合并将其与另一个集合进行比较。例如:
is 'a' in [b, c, d] ? no don't add a
is 'b' in [b, c, d] ? yes add b
is 'c' in [b, c, d] ? yes add c
Result: [b, c]
请注意,您不需要遍历第二组?您从未评估d
,但您已经知道它不在第一个列表中。您已经检查了第一个列表中的每个项目,因此“d”无法与[a, b, c]
匹配。
for (int i = 0; i < personA.size(); i++) {
Book ndx = personA.get(i);
if (personB.contains(ndx)) {
sameBooks.add(ndx);
}
}
return sameBooks;
答案 4 :(得分:0)
您可以尝试intersection()中的subtract()和CollectionUtils方法。
intersection()方法为您提供包含公共元素的集合,而subtract()方法为您提供了所有不常见的元素。
他们也应该照顾类似的元素
我相信您的Book类应该实现Comparator接口,以便您可以正确使用它。
答案 5 :(得分:0)
这是一个java 8流媒体解决方案:
import java.util.List;
import java.util.stream.Collectors;
class Class {
public static List<Book> commonBooks(Person a, Person b) {
List<Book> personA = a.getRead();
List<Book> personB = b.getRead();
return personA.stream()
.filter(personB::contains)
.collect(Collectors.toList());
}
}