قضية مع بيماب الجوافة و لينكدهاشماب
-
12-12-2019 - |
سؤال
هل من الممكن في الجوافة,
لإجراء بحث عكسي في
BiMap
للقيم الرئيسية والمتعددة?على وجه التحديد ، لدي مفتاح وقيم متعددة المقابلة ، أريد الحصول على مفتاح من قيمة.لتخزين قيم متعددة في
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
لتعيين قيم متعددة إلى مفتاح ، ولكن أشك في أنه يلبي الاحتياجات الخاصة بك.
- أشك في أنها فكرة جيدة للبحث عن مفتاح باستخدام القيم (عندما يكون لديك قيم متعددة تعيينها إلى مفتاح واحد) ، من أجل القيام بذلك يجب أن تكون القيمة الخاصة بك فريدة من نوعها والنظر في بنية البيانات الخاصة بك (وهو مثل
Map<Key, Collection<Value>
) لا يمكن ضمان أن يكون لها قيم فريدة. - الخيار الآخر مع الجوافة هو
BiMap
الأمر الذي يتطلب قيما فريدة ويمكن أن يوفر تعيينات عكسية (قيمة -> مفتاح) ولكن نظرا لأنك تحتاج إلى تعيين قيم متعددة لنفس المفتاح ، فهذا أيضا ليس مناسبا.
كما تضمين التغريدة يقول في جوابه إلى السؤال 2 الخاص بك ، يمكنك جعل بنفسك ListMultimap
يستخدم LinkedHashMap
كخريطة دعم لها باستخدام Multimaps.newListMultimap
الطريقة.
لسؤالك 1 ، حيث لديك مفاتيح تعيينها إلى قيم متعددة (أي.a Multimap
) ، يمكنك استخدام الطريقة Multimaps.invertFrom
لإنشاء نسخة مقلوبة من النسخة الأصلية Multimap
للقيام بالبحث العكسي على.أيضا ، يمكنك إنشاء ملف ImmutableListMultimap
نسخة من الأصل واستخدامها inverse()
طريقة للحصول على معكوس ، على الرغم من أن هذا مجرد الذهاب لنسخ الأصلي تماما مثل Multimaps.invertFrom
هل (على الرغم من أنه سوف مخبأ ذلك المكالمات المتكررة ل inverse()
إرجاع نفس النسخة.)
من المحتمل أن يكون هذا الأمر يستحق العناء إذا كنت لا تمانع في استهلاك الذاكرة الإضافية ، وسترغب في إجراء عمليات بحث عكسية متعددة ، ولا تحتاج إلى النسخة العكسية للبقاء على اطلاع دائم بالتغييرات التي تطرأ على النسخة الأصلية التي تحدث بعد إنشائها.إذا كنت ترغب فقط في البحث عن المفاتيح التي يتم تعيينها إلى قيمة محددة واحدة ، فيمكنك القيام بذلك في تكرار واحد للإدخالات دون إنشاء نسخة كاملة.