2017-04-02 14 views
0

TreeMap型を使用してコレクションを定義しました< String、List <ペア< Integer、String >>>ペアがクラスです私が定義した:マップ内のキーを返す<String、List <Pair <Integer、String >>>

public class Pair<L,R> { 
    private L l; 
    private R r; 
    public Pair(L l, R r) { 
     this.l = l; 
     this.r = r; 
    } 
public L getL() {return l;} 
public R getR() {return r;} 
public void setL(L l){this.l = l;} 
public void setR(R r){this.r = r;} 

} 

特定の文字列値を含むリストとペアになっている文字列(TreeMapキー)を返したいとします。たとえば、リストのペアの1つに格納されているString "bob"があり、 "bob"が入っているペアのリストに関連付けられているTreemapのキー(文字列)を返したいとします。これをどうやってやりますか?

+0

逆マッピングを保持し、一緒に両方を維持するために別のマップを作成します。もう一つの方法は、(entrySet()を使って)マップ内のすべてのエントリを繰り返し処理し、各リストでその値を検索することです。 – ajb

+0

コードの作成に問題があります...特定の値を含む複数のキーがある可能性があるので、私の関数はコレクション< String>を返します –

+0

私はあなたのアプリケーションの他の部分のキーでリストを参照する必要があると思いますキーを使ってリストを辞書順に反復する。それ以外の場合は、このデータ構造は必要なものとまったく逆です。 –

答えて

0

これは基本的に逆引きです。値に関連付けられたキーのmapがあり、関連付けられた値が何らかの条件を満たすキーを探したいとします。悪いケースでは、テーブルの参照が非常に高価になることがあります。マップ内のすべてのエントリにアクセスする可能性があるためです。

まずは、以下のように非常に簡単なことをします。私はPairクラスを少し修正する自由を取った。次はあなたの要件に従ってキーkey2を出力します。

public class ReverseLookup { 
    static class Pair<L,R> { 
     private L l; 
     private R r; 
     public Pair(L l, R r) { 
      this.l = l; 
      this.r = r; 
     } 
     public L getL() {return l;} 
     public R getR() {return r;} 
     public void setL(L l){this.l = l;} 
     public void setR(R r){this.r = r;} 

     public static <L, R> Pair<L, R> right(List<Pair<L, R>> pairs, R rVal) { 
      for (Pair<L, R> pair : pairs) { 
       if (rVal != null && rVal.equals(pair.getR())) 
        return pair; 
      } 
      return null; 
     } 
    } 

    public static void main(String[] args) { 
     String lookFor = "bob"; 
     Map<String, List<Pair <Integer, String>>> listOfPairs = new TreeMap<>(); 
     listOfPairs.put(
      "key1", Arrays.asList(new Pair("2", "carol"), new Pair(4, "david")) 
      ); 
     listOfPairs.put(
     "key2", Arrays.asList(new Pair("0", "alice"), new Pair(1, "bob")) 
     ); 
     for (Map.Entry<String, List<Pair<Integer, String>>> entry : listOfPairs.entrySet()) { 
      // entry is a mapping from string -> list of pairs Integer, String 
      List<Pair<Integer, String>> pairs = entry.getValue(); 
      if (Pair.right(pairs, lookFor) != null) { 
       System.out.println(entry.getKey()); 
      } 
     } 
    } 
} 
0

私は内部から作業する述語を作成します。私はあなたがその論理に従うことを願っています。これは、 "Bob"を持つ最初のリストを見つけ、そのキーを取得します。

Predicate<Pair<Integer, String>> pairHasBobPred = pair -> ((String) pair.getR()).equals("Bob"); 

Predicate<String> keyHasBobPred = key -> myTree.get(key).stream() 
                .anyMatch(pairHasBobPred::test); 

String keyWithBob = myTree.keySet().stream() 
            .filter(keyHasBobPred::test) 
            .findFirst() 
            .get(); 
関連する問題