2017-08-11 7 views
2

大文字と小文字が区別されるため、以下のコードでは 'ladies'という出力が正しく返されます。大文字と小文字を区別しない明示的な順序付けguava

import com.google.common.collect.SortedSetMultimap; 
import com.google.common.collect.TreeMultimap; 
import com.google.common.collect.Ordering; 

private static final Ordering<String> PRODUCT_ORDER = Ordering 
      .explicit("men","ladies") 
      .reverse(); 


private void testGuavaOrdering() { 
     SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap 
       .create(Collections.reverseOrder(), PRODUCT_ORDER); 
     onlineAreaPriorityCountMap.put(1, "men"); 
     onlineAreaPriorityCountMap.put(1, "men"); 
     onlineAreaPriorityCountMap.put(1, "ladies"); 
     onlineAreaPriorityCountMap.put(1, "ladies"); 
     System.out.println(onlineAreaPriorityCountMap.values().iterator().next()); 
    } 

しかし、以下のコードは動作しません。私は男性から男性に変更すると例外がスローされます。

private static final Ordering<String> PRODUCT_ORDER = Ordering 
      .explicit("Men","Ladies") 
      .reverse() 


private void testGuavaOrdering() { 
     SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap 
       .create(Collections.reverseOrder(), PRODUCT_ORDER); 
     onlineAreaPriorityCountMap.put(1, "men"); 
     onlineAreaPriorityCountMap.put(1, "men"); 
     onlineAreaPriorityCountMap.put(1, "ladies"); 
     onlineAreaPriorityCountMap.put(1, "ladies"); 
     System.out.println(onlineAreaPriorityCountMap.values().iterator().next()); 
    } 

例外:

Exception in thread "main" com.google.common.collect.Ordering$IncomparableValueException: Cannot compare value: men 
    at com.google.common.collect.ExplicitOrdering.rank(ExplicitOrdering.java:46) 
    at com.google.common.collect.ExplicitOrdering.compare(ExplicitOrdering.java:40) 
    at com.google.common.collect.ReverseOrdering.compare(ReverseOrdering.java:38) 
    at java.util.TreeMap.compare(TreeMap.java:1295) 
    at java.util.TreeMap.put(TreeMap.java:538) 
    at java.util.TreeSet.add(TreeSet.java:255) 
    at com.google.common.collect.AbstractMapBasedMultimap.put(AbstractMapBasedMultimap.java:195) 
    at com.google.common.collect.AbstractSetMultimap.put(AbstractSetMultimap.java:121) 
    at com.google.common.collect.TreeMultimap.put(TreeMultimap.java:78) 
    at TestMap.testGuavaOrdering(TestMap.java:38) 
    at TestMap.main(TestMap.java:32) 

小文字を区別しないが、グアバで比較する場合を行うにはどのように?私はそれを見たよう

+0

Shouldn大文字と小文字の違いがターゲットマップにあるのでしょうか?または、あなたのコントロールの外に明示的に注文していますか? – shmosel

+0

重複していると思われる人には、質問をよく読んでください。他の回答が関連していると思われる場合は、それをテストして確認してください。 – shmosel

+0

私はカスタム明示的な注文を持っているので、重複した質問とは思わない。 – user2057006

答えて

4

あなたはOrdering自体は、大文字と小文字を区別しないことはできませんが、あなたはすべて小文字その値を作ることができれば、あなたがランクインする前に小文字に入力を変換Comparatorでそれをラップすることができます:

private static final Ordering<String> PRODUCT_ORDER = Ordering 
     .explicit("men","ladies") 
     .reverse(); 


private static void testGuavaOrdering() { 
    SortedSetMultimap<Integer, String> onlineAreaPriorityCountMap = TreeMultimap 
      .create(Collections.reverseOrder(), 
        Comparator.comparing(String::toLowerCase, PRODUCT_ORDER)); 
    onlineAreaPriorityCountMap.put(1, "Men"); 
    onlineAreaPriorityCountMap.put(1, "men"); 
    onlineAreaPriorityCountMap.put(1, "Ladies"); 
    onlineAreaPriorityCountMap.put(1, "ladies"); 
    System.out.println(onlineAreaPriorityCountMap.values().iterator().next()); 
} 
0

あなたは、少なくとも3つのオプションを持っている(生存能力を降順で、つまり私は、可能な場合は最初を使用してお勧めする):

  1. は、ケースを扱うTreeMultimap、1にカスタムComparatorを提供しますあなたはそれを望んでいます(実装のためのshmoselの答えを見てください)。
  2. ExplicitOrderingのラッパー/ファクトリを作成し、すべての値を作成時およびrank()メソッドで同じ大文字にします。暗黙の順序付けのために渡される値に影響を与えない場合は、これを使用できます。ただし、比較のためにオプション1(文字列を小文字に変換してからExplicitOrderingに渡す)とコンストラクタに事前変換された入力文字列を渡すこともできます。
  3. 大文字小文字を区別しない方法で、equals()(およびhashcode())を実装する文字列のラッパーを指定します。あなたの注文のためにそれらを使用し、地図キーを使用してください。
+0

ポイント3については、 'compareTo()' – sargue

+1

@sargue noをオーバーライドする必要があります。なぜなら、 'ExplicitOrdering'は要素に対して' compareTo() 'を呼び出さず、マップ内でランクルックアップを実行するからです。それに加えて、要素はComparableを実装する必要はありません。したがって、オーバーライドするcompareTo()も存在するという保証はありません。 – Thomas

+0

私はあなたの2番目の解決策を理解していません。例を投稿する心ですか? – shmosel

関連する問題