2015-02-20 11 views
9

Я относительно новичок в Java, и у меня есть вопрос о том, какой тип структуры данных лучше всего подходит для моего случая. У меня есть набор данных, которые по сути являются парами ключ-значение, однако каждое значение может соответствовать нескольким клавишам, и каждый ключ может соответствовать нескольким значениям. Упрощенный пример будет:Какая структура данных Java лучше всего подходит для двунаправленного многозначного сопоставления

  • Red-яблочный
  • Green-яблочного
  • Красной Клубника
  • Green-Виноград
  • пурпурно-виноград

Учитывая приведенный выше пример, Я должен иметь возможность возвращать то, что у меня есть, и/или какие красные фрукты у меня есть. Фактические данные будут генерироваться динамически на основе входного файла, где каждый набор будет где угодно от 100-100 000 значений, и каждое значение может соответствовать сотням значений в другом наборе.

Что было бы самым эффективным способом хранения и анализа этих данных? Я предпочел бы решение как родное для java, а не нечто вроде внешней базы данных.

This question связан, но я не уверен, как применить решение в моем случае, учитывая, что мне нужно будет присвоить несколько значений каждому ключу в обоих направлениях.

+0

Как насчет карты? http://docs.oracle.com/javase/7/docs/api/java/util/Map.html – Koogle

+0

Существует также этот вопрос: http://stackoverflow.com/questions/2571652/java-many-to- many-association-map – Josh

+0

@Josh - Спасибо, я не нашел этот вопрос в моем поиске. Я рассмотрю решения, чтобы проверить, могу ли я успешно реализовать их для своих данных. – user4588937

ответ

1

Предлагаю вам использовать Guava's Table состав. Используйте цвет в качестве ключей и фруктов в качестве ключа столбца или наоборот. В частности, HashBasedTable хорошо подходит для вашего случая.

В соответствии с вашим вариантом использования вам не нужно ничего хранить для значений. Однако эти Table s не допускают значений null. Вы можете использовать манекен Boolean или любую другую статистическую полезную стоимость, т.е. дату и время включения, пользователя, количество цветов/фрукты пара и т.д.

Table имеют методы, необходимые, например, column() и row(). Имейте в виду, что документы говорят, что эти структуры оптимизированы для доступа к строке.Это может быть хорошо для вас, если вы планируете доступ одним ключом больше, чем другим.

3

Поскольку у вас не может быть дубликатов ключей в Map, вы можете создать Map<Key, List<Value>>, или, если можно, используйте Guava's Multimap.

Multimap<String, String> multimap = ArrayListMultimap.create(); 
multimap.put("Red", "Apple"); 
multimap.put("Red", "Strawberry"); 

System.out.println(multimap.get("Red")); // Prints - [Apple, Strawberry] 

Но проблема в том, вы не можете попросить ключи от данного объекта, я буду продолжать смотреть и делать и редактировать, если я найду что-то еще, надеюсь, что это помогает.

Тем не менее, вы можете сделать обратную операцию, итерации карты и поиска ключей для объекта.

+1

* «Но проблема в том, что вы не можете попросить ключи данного объекта. "* Похоже, что это будет разрешено BiMultiMap. Не уверен, существует ли это, но это то, что он будет называть. Или Directed Graph, индексированный по именам узлов. –

+0

Можете ли вы не обернуть два из них внутри пользовательского объекта, чтобы достичь этого –

0

Вы можете создать свою собственную структуру

public class MultiValueHashMap<K, V> { 
    private HashMap<K, ArrayList<V>> multivalueHashMap = new HashMap<K, ArrayList<V>>(); 

    public static void main(String[] args) { 
     MultiValueHashMap<String, String> multivaluemap = new MultiValueHashMap<String, String>(); 
     multivaluemap.put("Red", "Apple"); 
     multivaluemap.put("Green", "Apple"); 
     multivaluemap.put("Red", "Strawberry"); 
     multivaluemap.put("Green", "Grapes"); 
     multivaluemap.put("Purple", "Grapes"); 

     for(String k : multivaluemap.keySet()){ 
      System.out.println(k + " : " + multivaluemap.get(k).toString()); 
     } 
    } 

    public void put(K key, V value){ 
     if (multivalueHashMap.containsKey(key)){ 
      ArrayList<V> values = multivalueHashMap.get(key); 
      values.add(value); 
     }else{ 
      ArrayList<V> values = new ArrayList<V>(); 
      values.add(value); 
      multivalueHashMap.put(key, values); 
     } 
    } 

    public Set<K> keySet(){ 
     return multivalueHashMap.keySet(); 
    } 

    public ArrayList<V> get(K key){ 
     return multivalueHashMap.get(key); 
    } 
} 

пользовательских данных Выходные данные должны быть

Красный: [Apple, клубника]

Фиолетовый: [виноград]

Зеленый: [ Apple, Grapes]