كيف يمكنني استخدام حلقة foreach في جاوة إلى حلقة من خلال القيم في HashMap?

StackOverflow https://stackoverflow.com/questions/448122

  •  19-08-2019
  •  | 
  •  

سؤال

أنا أحاول ترجمة التعليمات البرمجية التالية:

private String dataToString(){
    Map data = (HashMap<MyClass.Key, String>) getData();
    String toString = "";
    for( MyClass.Key key: data.keySet() ){
        toString += key.toString() + ": " + data.get( key );
    return toString;
}

أحصل على خطأ في السطر الذي يقول:

incompatible types
found : java.lang.Object
required: MyClass.Key

على getData() الأسلوب بإرجاع Object (ولكن في هذه الحالة Object عاد لديه HashMap الهيكل). MyClass.Key هو التعداد التي خلقت لأغراض بلدي التطبيق (في صف آخر الملف MyClass).

عندما خلق حلقة foreach مع نفس الهيكل في MyClass.java, أنا لم تواجه هذه المشكلة.

ما الخطأ الذي فعلته ؟

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

المحلول

وهناك طريقة أكثر كفاءة قليلا للقيام بذلك:

  Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData(); 
  StringBuffer sb = new StringBuffer();
  for (Map.Entry<MyClass.Key,String> entry : data.entrySet()) {
       sb.append(entry.getKey());
       sb.append(": ");
       sb.append(entry.getValue());
   }
   return sb.toString();

إذا كان ذلك ممكنا، وتحديد "getData" لذلك لا تحتاج المدلى بها.

نصائح أخرى

والتغيير:

Map data = (HashMap<MyClass.Key, String>) getData();

إلى

Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData();

والمشكلة هي أن data.keySet() إرجاع Collection<Object> إذا كانت البيانات هو مجرد Map. بمجرد جعله عام، سوف keySet() بإرجاع Collection<MyClass.Key>. حتى أفضل ... تكرار عبر entrySet()، والتي سوف تكون Collection<MyClass.Key, String>. أنه يتجنب عمليات البحث تجزئة إضافية.

لقد وجدت هذا مثال بسيط في جافا المنتدى.لها الجملة هي مشابهة جدا إلى قائمة foreach, الذي كان ما كنت أبحث عنه.

import java.util.Map.Entry;
HashMap nameAndAges = new HashMap<String, Integer>();
for (Entry<String, Integer> entry : nameAndAges.entrySet()) {
        System.out.println("Name : " + entry.getKey() + " age " + entry.getValue());
}

[تحرير:] أنا اختبرت وأنها تعمل تماما.

هل يمكن انتزاع entrySet بدلا من ذلك، لتجنب الحاجة الطبقة الرئيسية:

private String dataToString(){    
    Map data = (HashMap<MyClass.Key, String>) getData();    
    String toString = "";    
    for( Map.Entry entry: data.entrySet() ) {        
        toString += entry.getKey() + ": " + entry.getValue();
    }    
    return toString;
}

Motlin هو الجواب الصحيح.

لدي اثنين من ملاحظات...

  1. لا تستخدم toString += ..., ولكن استخدام StringBuilder بدلا من إلحاق البيانات إلى ذلك.

  2. الزهر الذي اقترح مارتن سوف تعطيك لحالها الإنذار ، التي لن تكون قادرة على التخلص من ، لأنه حقا غير آمنة.

طريقة أخرى ، دون سابق إنذار (ومع بـ stringbuilder):

private String dataToString(){
    Map<?, ?> data = (Map<?, ?>) getData();
    StringBuilder toString = new StringBuilder();
    for (Object key: data.keySet()) {
        toString.append(key.toString());
        toString.append(": ");
        toString.append(data.get(key));
    }
    return toString.toString();
}

يعمل هذا لأن toString الطريقة التي يمكنك الاتصال على key يتم تعريف في فئة الكائن, لذلك أنت لا تحتاج إلى صب على الإطلاق.

باستخدام entrySet بل هو أفضل طريقة ، كما أنها لا تحتاج إلى القيام نظرة أخرى في الخريطة.

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