2017-02-08 15 views
2

私は2人の異なる人が読んで比較した2冊の本のリストを使用しようとしています。最初のリストのブック(String titleとString authorで構成されたコンストラクタ)が他のリストのブックの1つと等しい場合、commonBooksリストに追加します。これは私がこれまでに得たものであるが、私はこの提案を得続ける:Java 8 ArrayListの等価性

「を無効にするための変更」または「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

あなたのプログラム内のすべての条件が値を返す必要があります。そうでなければ、条件ブロックの外側にあるものを最後に返す必要があります。これは、条件を満たすかどうかにかかわらず常に値が返されるようにする単なる方法です。これは、値が返されることを期待するメソッドに適用されます。または、すべてのreturn文を削除し、コンパイラが提案するようにメソッドをvoidとしてマークしてください:) – Prathap

答えて

1

これは私がこれまでに得たものであるが、私はこの提案を得続ける:あなたのメソッドの戻り値内のすべての論理が流れていない「 return文を追加する」または「voidへの変更」

メソッドシグネチャに指定された戻り値の型(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

これは警告を修正しますが、コードはまだ破損しています。personA.size()> = personB.size()空のリストを返す... – tucuxi

+0

ありがとう、私はあなたの助けに感謝します。 –

0

戻り型がありますArrayList。さまざまな条件ブロックにreturnステートメントを追加しましたが、commonBooksメソッドの閉じ括弧の直前にあるすべての条件ブロックの外にreturnステートメントを追加しませんでした。

メソッドの閉じ括弧の直前のelseまたはifブロックの外側にあるArrayListを返す必要があります。

else { 
     return sameBooks; 
} 

    //add return statement here  

} //closing parenthesis of commonBooks method 
0

あなたはこれを考えすぎています。

コレクション[a, b, c]と別のコレクション[b, c, d]があるとします。

1つのコレクションを繰り返して比較するだけで済みます。例:

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] 

2番目のセットをループする必要はありませんでした。あなたはdを評価したことはありませんが、最初のリストにはないことはすでに分かっています。既に最初のリストのすべてのアイテムをチェックして、[a, b, c]に対して 'd'が一致する方法はありません。

for (int i = 0; i < personA.size(); i++) { 
    Book ndx = personA.get(i); 
    if (personB.contains(ndx)) { 
     sameBooks.add(ndx); 
    } 
} 
return sameBooks; 
0

はあなたがCollectionUtilsからintersection()subtract()方法を試すことができますJava Compare Two Lists

を参照してください。

intersection()メソッドは共通の要素を含むコレクションを提供し、subtract()メソッドはあなたにすべての珍しいものを与えます。

彼らはまた、私はあなたがこれを適切に使用することができますので、あなたのBookクラスはComparatorインタフェースを実装する必要があります信じて同様の要素

の世話をする必要があります。

+1

セットと 'retainAll'を使う方が簡単です - 外部依存関係は必要ありません。あなたはまた、私のコードで何が間違っているのOPのオリジナルの質問に答えることはありません – tucuxi

1

メソッドでArrayListが返されると宣言した場合、コード内のすべての可能なパスはArrayListを返す必要があります。VHSのanswerは修正点を正確に指摘している:ArrayListを返す1か所だけで終了し、すべてのパスが通過しなければならない。しかし、HashSet Sを使用して

HashSet<Book> readByA = new HashSet<>(a.getRead()); 
readByA.retainAll(b.getRead()); // remove all books that b has not read 
return new ArrayList<>(readByA); 

はあなたBookクラスでequals()hashCode()メソッドを実装しているために必要です。

あなたの元の質問を超えて別の修正では、単純なコードを使用することです。多くのIDEがあなたのためにそれらを実装するために提供します。一方、多数の書籍については、これはあなたの現在のコードよりはるかに高速です。


personA.size() >= personB.size()場合、それは空のリストを返すよう、元のコードはまた、少なくとも1つの主要なバグがあります。たとえば、2つの同一のリストがある場合、現在は両方の書籍に共通するものはありません。

セットせずに、再びこの時間をそれを書き換え:、すべてのものが等しいことを

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; 

注意を、短いコードを読んで、長いコードの断片よりも理解しやすいです。それはあなたが2行(66%!)を保存しないと、もはや2によって混乱している...

ArrayList<Book> readByA = a.getRead(); 
// ... 
for (int i = 0; i < readByA.size(); i++) { 
    Book b = readByA.get(i); 

... ... ...

for (Book b : a.getRead()) { 

を好む理由の一つであり補助変数、iおよびreadByAは、もはや実際には必要ありません。ここで

+0

ありがとう、それは私のプロジェクトのために少し進んでいる。 –

+0

もう少しコードを追加しましたが、今回はセットを使用しません。現在のコードは、VHSの修正があっても、過度に複雑であり、多くの入力に対して間違った結果をもたらすことに注意してください。 – tucuxi

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

OPは既に動作しているとみなすことができます(そうでなければ、contains()は失敗します)。 – tucuxi

+0

偉大な、私は答えのそれをカットします。 – Andreas