1
@SuppressWarnings("unchecked")
public static final Ordering<EmailTemplate> ARBITRARY_ORDERING = (Ordering)Ordering.arbitrary();

public static final Ordering<EmailTemplate> ORDER_BY_NAME = Ordering.natural().nullsFirst().onResultOf(GET_NAME);

public static final Ordering<EmailTemplate> ORDER_BY_NAME_SAFE = Ordering.allEqual().nullsFirst()
            .compound(ORDER_BY_NAME)
            .compound(ARBITRARY_ORDERING);

EmailTemplate を注文するために使用するコードを次に示します。EmailTemplate のリストがある場合、リストの null 要素を最初に表示し、次に null 名の要素を表示し、次に自然な名前の順序で表示し、同じ名前の場合は任意の順序で表示します。


それは私がすべきことですか?「allEqual」でコンパレータを開始するのは奇妙に思えます...

また、Ordering.arbitrary() は Ordering を返す静的メソッドであるため、これを処理する最善の方法は何だろうと考えています。それを使用するエレガントな方法はありますか?私はこの種の役に立たない警告付きの行があまり好きではありません:

@SuppressWarnings("unchecked")
public static final Ordering<EmailTemplate> ARBITRARY_ORDERING = (Ordering)Ordering.arbitrary();

ちなみに、ドキュメントには次のように書かれています。

(identity equals)をcompare(a, b) == 0意味するすべてのオブジェクトの任意の順序を返します。a == b課された順序には何の意味もありませんが、VM の存続期間中は一定です。

これは、この Ordering と比較されているオブジェクトがガベージ コレクションされないことを意味しますか?

4

2 に答える 2

4

2番目の質問について:いいえ。Guava は、オブジェクトの ID ハッシュ コードを使用して、オブジェクトを任意に並べ替えます。

最初の質問について: 比較チェーンを使用して名前で並べ替え、次に任意の順序で並べ替えます。

private class ByNameThenArbitrary implements Comparator<EmailTemplate> {
    @Override
    public int compare(EmailTemplate e1, EmailTemplate e2) {
        return ComparisonChain.start()
                              .compare(e1.getName(), e2.getName(), Ordering.natural().nullsFirst(),
                              .compare(e1, e2, Ordering.arbitrary())
                              .result();
    }
}

次に、テンプレートを最初に null で並べ替える実際の順序を作成します。

private static final Ordering<EmailTemplate> ORDER = 
    Ordering.fromComparator(new ByNameThenArbitrary()).nullsFirst();

ただし、テストされていません。

于 2012-09-07T10:50:17.747 に答える
3

私はかなり確信しています、あなたはそれを複雑にしすぎています:

  • Ordering.arbitrary()任意で動作し、Object制限compoundする必要はありませんEmailTemplate
  • 比較されるときは言うnullsFirst()ことが優先nullされ、最後に適用することをお勧めします
  • 複数の定数を定義する必要はありません。すべて簡単なはずです

私は行くだろう

public static final Ordering<EmailTemplate> ORDER_BY_NAME_SAFE = Ordering
    .natural()
    .onResultOf(GET_NAME)
    .compound(Ordering.arbitrary())
    .nullsFirst();

しかし、私はそれをテストしていません。


ここで紛らわしいのは、方法compoundnullsFirst動作です。前者でthisは優先され、後者ではnull勝利のテストが行​​われます。どちらも論理的です:

  • compound左から右に動作します
  • nullsFirst最初にnullをテストする必要があります。そうしないと、期待値が得られます

しかし、まとめるとややこしい。


これは、この Ordering と比較されているオブジェクトがガベージ コレクションされないことを意味しますか?

いいえ、弱参照を使用しています。オブジェクトが他の場所で参照されていないときはいつでも、ガベージ コレクトされる可能性があります。これは、「VM の存続期間中、順序は一定である」という矛盾ではありません。既存のオブジェクトはもはや比較できないからです。

Ordering.arbitrary()は実際には任意であり、 ではなくオブジェクトの ID に基づいていることに注意してくださいequals。つまり、

 Ordering.arbitrary().compare(new String("a"), new String("a"))

0 を返しません。

「equals互換の任意の順序付け」が実装できるのだろうか。

于 2012-09-07T10:49:37.560 に答える