2011-09-10 7 views
2

は、重複キーと値を格納するには、次の質問を考えてみましょう:は、重複キーを持つマップを作成

  1. は、属性として名前、SALとDOBを持つクラスの従業員があると。 EmployeeのオブジェクトをMapに格納し、そのキーがEmployeeの名前になりたい。名前は重複することができます。

  2. マップ内に10個のオブジェクトを追加した後。私は入力された8番目のオブジェクトを取得したい。

This重複したキーを持つオブジェクトを追加する一つの解決策であるが、マップを表示するには、同じキーを持つすべての値が一緒に表示されますので、質問の第二の部分のために、これは動作しないでしょう。

この状況でオブジェクトが追加された順序はどのように維持されますか? equalsメソッドとhashcodeメソッドを変更して、何らかの方法で要素を追加した後、挿入された順序で後で取得できますか?

+0

すべてのエントリ/従業員または矛盾するキー/名前の挿入順に興味がありますか? – Gevorg

+0

2つのシナリオ:1]同じキーと異なるsalとdobを持つ10人の従業員をすべて追加するとします。 2] 10人の従業員が重複キーを持っています。これらの両方のシナリオで、どのようにn番目のレコードをマップから取得しますか? –

+0

http://stackoverflow.com/questions/1062960/map-implementation-with-duplicate-keysの可能な複製 –

答えて

0

要件は何らかの形で矛盾しています。一方の側では、あるキーに対していくつかの値が可能でなければなりません。もう一方の側では、キーに対して返される値は1つだけです。さらに、配列の検索が可能でなければなりません。名前に基づいた高速アクセスのためのハッシュマップと、挿入の順序を保持するリストとを含む専用のデータ構造を設計する際に最も近い近似を見る。アクセスは、全体のシーケンス番号、または名前の名前とインデックスに基づいて行われます。

public class Employee { 
    public String name; public int sal;   
    public Employee() {name = ""; sal = 0;} 
    public Employee(String name, int sal) { 
     this.name = name; this.sal = sal; 
    } 
    @Override public String toString() {return "(" + name + "," + sal + ")";} 
} 

public class Team { 
    private Map<String, ArrayList<Employee>> employees = 
      new HashMap<String, ArrayList<Employee>>(); 
    private ArrayList<Employee> order = new ArrayList<Employee>(); 

    public void addEmployee(Employee e) { 
     ArrayList<Employee> list = employees.get(e.name);  
     if (list == null) { 
      list = new ArrayList<Employee>(); 
      employees.put(e.name, list); 
     } 
     list.add(e); 
     order.add(e); 
    }   
    public int getNumEmployees() {return order.size();} 
    public Employee getEmployee(int n) {return order.get(n - 1);}  
    public int getNumEmployees(String name) { 
     ArrayList<Employee> list = employees.get(name); 
     return list == null ? 0 : list.size(); 
    } 
    public Employee getEmployee(String name, int n) { 
     ArrayList<Employee> list = employees.get(name); 
     return list == null ? null : list.get(n - 1); 
    } 
} 

// Test: 
Team team = new Team(); 
team.addEmployee(new Employee("Bob", 11)); 
team.addEmployee(new Employee("Bob", 12)); 
team.addEmployee(new Employee("Eve", 13)); 
team.addEmployee(new Employee("Eve", 14)); 

System.out.println("Num all: " + team.getNumEmployees()); 
System.out.println("3rd: " + team.getEmployee(3)); 
System.out.println("Num Bobs: " + team.getNumEmployees("Bob")); 
System.out.println("2nd Bob: " + team.getEmployee("Bob", 2)); 
1

2つのコンテナがありますか?従業員に名前をマッピングするためのもの(stackoverflow question you mentionedのようなもの)、従業員に番号をマッピングするもの。あなたはマルチマップとarraylistを集約する "外側の"コンテナを作ることができます。

+0

あまりにも多くのメモリを使用しませんか?インタビュアーは、equalsメソッドとhashcodeメソッドを変更することで実装できると言いましたが、どうしたらよいかわかりません。 –

+0

@neeraj:うーん、ハッシュコードで行うことはできますが、醜いハックになるでしょう。たとえば、Empolyeeにフィールド「hashcode」を含め、-1に初期化し、ハッシュテーブルに挿入する前にhashtable.size()に設定します。同じオブジェクトでない場合、2人の従業員が異なるように「等しい」を変更します。これはすべきですが、それは汚いですし、間違いなくコードの他の部分でいくつかの問題を引き起こすでしょう。 – Vlad

1

あなたがしようとしていることは、ArrayListを使って簡単に実装できます。これは、使用すべきデータ構造です。

+0

私が言及した例ではArrayListを使用していますが、表示には** Map ** –

+0

に挿入された順序ではなく、同じキーのオブジェクトが一緒に表示されるためです@neeraj私が言っているのは、あなたのニーズに合わせてマップを必要としないかもしれないということです。単にEmployeesをArrayListに追加するだけです。これにより、リストに追加する順序が維持されます。なぜあなたに質問するのですか、なぜこの場合の地図が必要ですか? – Marcelo

+0

私はそれを必要としません、これはインタビューで尋ねられました。単なるシナリオです...重複キーを持つマップに値を格納する必要があるかもしれません... –

2

私はLinkedHashMultimapGuava)と考えています。インデックスで直接8番目のエントリを取得することはできませんが、Iterables.get(Iterable iterable, int position)のようなものを使用して取得できます。

+0

これはJavaコレクションを使用して実装できませんか?インタビュアーは、equalsメソッドとhashcodeメソッドを変更する方法を教えていましたが、実装方法はわかりません。 –

+0

@neeraj: 'LinkedHashMultimap'は(内部的に)基本的に' LinkedHashMap > 'plus追加された順番でエントリを格納する 'LinkedHashSet >'したがって、JDKクラスのみを使用しても同じ効果を得ることができます。 – ColinD

関連する問題