سؤال

هل من الممكن في الجوافة,

  1. لإجراء بحث عكسي في BiMap للقيم الرئيسية والمتعددة?على وجه التحديد ، لدي مفتاح وقيم متعددة المقابلة ، أريد الحصول على مفتاح من قيمة.

  2. لتخزين قيم متعددة في LinkedHashMap?على وجه التحديد ، أريد تخزين قيم متعددة المفاتيح بترتيب ما وبالتالي يمكنني الحصول على موضع رئيسي في القائمة.

هل كانت مفيدة؟

المحلول

الإعلانية.1. نعم, من الممكن القيام بحث عكسي مع BiMap<K, V>, فقط اتصل inverse على BiMap و يمكنك الحصول على inversed BiMap<V, K> عرض من BiMap.

مثال (مأخوذة من الجوافة اختبار جناح):

public void testMapConstructor() {
  /* Test with non-empty Map. */
  Map<String, String> map = ImmutableMap.of(
      "canada", "dollar",
      "chile", "peso",
      "switzerland", "franc");
  HashBiMap<String, String> bimap = HashBiMap.create(map);
  assertEquals("dollar", bimap.get("canada"));
  assertEquals("canada", bimap.inverse().get("dollar"));
}

الإعلانية.2. على افتراض انك يعني "أريد أن store الرئيسية -> متعددة [جمع] القيم" (Map<K, Collection<V>>), ListMultimap ربما هو ما تريد ، أكثر precisly ArrayListMultimap (يحافظ على قيم النظام) أو LinkedListMultimap (يحفظ كل مفاتيح وقيم النظام).إذا كان الكائن الخاص بك سوف تكون ثابتة لا ننصح بشدة استخدام ImmutableListMultimap.

يمكنك أيضا إنشاء الخاصة بك تنفيذ Multimap باستخدام مصنع (مطول بعض الشيء) أييمكنني استخدام:

private static <K, V> ListMultimap<K, V> makeLinkedArrayListMultimap() {
  return Multimaps.newListMultimap(Maps.<K, Collection<V>>newLinkedHashMap(), 
      new Supplier<List<V>>() {
        @Override public List<V> get() {
          return Lists.newArrayList();
        }
      });
}

public static void main(final String[] args) {
  final ListMultimap<String, String> multimap = makeLinkedArrayListMultimap();
  multimap.putAll("one", ImmutableList.of("zero", "three"));
  multimap.putAll("two", ImmutableList.of("three", "four", "three"));
  multimap.putAll("three", ImmutableList.<String>of()); // note that this doesn't add key to multimap
  multimap.put("four", "forty-two");

  System.out.println(multimap);
  // prints {one=[one, three], two=[three, four, three], four=[forty-two]}

  final List<String> listForOnes = multimap.get("one");
  System.out.println(listForOnes.get(0));
  // prints zero
}

P. S. نلقي نظرة على الجوافة ويكي, الذي هو شرح على حد سواء BiMap و Multimap.

نصائح أخرى

الأقرب في الجوافة هو Multiset لتعيين قيم متعددة إلى مفتاح ، ولكن أشك في أنه يلبي الاحتياجات الخاصة بك.

  1. أشك في أنها فكرة جيدة للبحث عن مفتاح باستخدام القيم (عندما يكون لديك قيم متعددة تعيينها إلى مفتاح واحد) ، من أجل القيام بذلك يجب أن تكون القيمة الخاصة بك فريدة من نوعها والنظر في بنية البيانات الخاصة بك (وهو مثل Map<Key, Collection<Value>) لا يمكن ضمان أن يكون لها قيم فريدة.
  2. الخيار الآخر مع الجوافة هو BiMap الأمر الذي يتطلب قيما فريدة ويمكن أن يوفر تعيينات عكسية (قيمة -> مفتاح) ولكن نظرا لأنك تحتاج إلى تعيين قيم متعددة لنفس المفتاح ، فهذا أيضا ليس مناسبا.

كما تضمين التغريدة يقول في جوابه إلى السؤال 2 الخاص بك ، يمكنك جعل بنفسك ListMultimap يستخدم LinkedHashMap كخريطة دعم لها باستخدام Multimaps.newListMultimap الطريقة.

لسؤالك 1 ، حيث لديك مفاتيح تعيينها إلى قيم متعددة (أي.a Multimap) ، يمكنك استخدام الطريقة Multimaps.invertFrom لإنشاء نسخة مقلوبة من النسخة الأصلية Multimap للقيام بالبحث العكسي على.أيضا ، يمكنك إنشاء ملف ImmutableListMultimap نسخة من الأصل واستخدامها inverse() طريقة للحصول على معكوس ، على الرغم من أن هذا مجرد الذهاب لنسخ الأصلي تماما مثل Multimaps.invertFrom هل (على الرغم من أنه سوف مخبأ ذلك المكالمات المتكررة ل inverse() إرجاع نفس النسخة.)

من المحتمل أن يكون هذا الأمر يستحق العناء إذا كنت لا تمانع في استهلاك الذاكرة الإضافية ، وسترغب في إجراء عمليات بحث عكسية متعددة ، ولا تحتاج إلى النسخة العكسية للبقاء على اطلاع دائم بالتغييرات التي تطرأ على النسخة الأصلية التي تحدث بعد إنشائها.إذا كنت ترغب فقط في البحث عن المفاتيح التي يتم تعيينها إلى قيمة محددة واحدة ، فيمكنك القيام بذلك في تكرار واحد للإدخالات دون إنشاء نسخة كاملة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top