web-dev-qa-db-ja.com

コンストラクターで.sort()を呼び出すことは、コンストラクターが機能してはならないというガイドラインに違反していますか?

果物のリストを保持するために、次のListがあるとします。

例:

_def fruits = ["Apple", "Orange", "Grapes"]
def fruitsBowl = ["Apple", "Grapes", "Orange"]

// Will print false
println(fruits.equals(fruitBowl))
_

.sort()を呼び出した後にのみ、両方のコレクションが等しくなります。

_fruits.sort()
fruitBowl.sort()

// Will print true
println(fruits.equals(fruitBowl))
_

もし私がBookクラスを持っていたとしたら、明らかにBookクラスにはlistの作者がいます。この例では、AuthorsクラスはComparatorを実装しています。

_class Book {

    private String title;
    private List<Author> authors;

    Book(title, authors){
        // code to initialize left out
        authors.sort()
    }
_

私の主な関心事はequals()メソッドです。 2つの本を比較すると、たとえ本のオブジェクトが同じであっても、著者のリストがソートされていない場合は、falseが返されます。

私がfruitsでsortを呼び出すのと同じ方法で.sort()を呼び出すと、Bookの著者リストを保持するコレクションでfruitsBowlをソートしますconstructor、それは悪い習慣ですか?

それが悪い習慣である場合、equalsメソッドが機能することを保証するために何をすべきですか?

更新:

コメントのように、私がSetを使用した場合は、それがより理にかなっています。なぜなら、本が著者のリストによって書かれている場合、各名前は一度だけ表示されるので、これを行うことも悪い習慣と見なされますか?

_class Book {

    private String title;
    private Set authorsSet;

    Book(title, authors){
       authorsSet = authors.toSet() 
    }
_

Setは一意の要素のコレクションであり、等価性テストは順序に関係なく正しく機能します。

1
user313955

コンストラクターで.sort()を呼び出すことは、コンストラクターが機能すべきではないというガイドラインの違反ですか?

有効なオブジェクトを作成するために.sort()を呼び出さなければならない場合。

有効なオブジェクトとは何ですか?有効なオブジェクトとは、オブジェクトに課した制約を満たすオブジェクトです。それらの制約は何ですか?あなたが何を言おうと。

var sortedList = new SortedList(unsortedList);

当然、実際的な制限があります。昨日、誰かがSpring Framework AnnotationConfigApplicationContextクラスについて 質問 と尋ねました。このクラスのインスタンス化は、アプリケーションで数百のフォームを登録して利用できるようにするため、彼のアプリケーションでは15秒かかります。ええと、15秒というのは、計算上かなり長い時間ですが、現在コンピューターにロードするのに時間がかかるアプリケーションがあります。

この男の問題は、コンストラクターが実行している作業量ではありません。それは彼がウェブアプリケーションのすべてのページロードでその仕事をしているということです。

「コンストラクターは実際の仕事をしてはいけません」は赤いニシンです。 適切な使用にさらに焦点を当てます。

11
Robert Harvey

誤解は、著者のListがないということです(学界のように著者の順序が重要でない限り-しかし、そのリストでソートを呼び出すことさえ考えないでしょう)、むしろあなたは持っています著者のSetまたはCollection

さらに、Listコントラクトは、いつでもソートされていないリストである可能性があることを意味するものを指定します。 .add()メソッドは最後に追加します常に

これはgroovyを扱っているため、_==_および.equals()- http://groovy-lang.org/style-guide.html#_equals_and_code_codeに関するドキュメントに注意することが重要です。

リストは、同じ項目が同じ順序で含まれている場合に等しくなります。 - http://docs.groovy-lang.org/latest/html/groovy-jdk/Java/util/List.html#equals(Java.util.List)

同じアイテムが含まれている場合、セットは同じです。 http://docs.groovy-lang.org/latest/html/groovy-jdk/Java/util/Set.html#equals(Java.util.Set)

コレクション内のアイテムの順序を気にしない場合は、リストを使用しないでください。リスト内のアイテムを並べ替えてリストの等価性を取得する場合、順序は関係ありません。

6
user313961