2015-12-21 4 views
2

У меня есть метод, который ставит значение в HashMap типа HashMap<String, Object[]> & возвращает тот же HashMap.Получить элементы массива из HashMap в Java

Код для ввода значения в HashMap:

doc = Jsoup.connect(url).get(); 
for(org.jsoup.nodes.Element element : doc.getAllElements()) 
{ 
    for(Attribute attribute : element.attributes()) 
    { 
     String option_ID=element.tagName()+"_"+attribute.getKey()+"_"+attribute.getValue(); 
     String HTMLText=element.text(); 
     int HTMLTextSize=HTMLText.length(); 
     if(!HTMLText.isEmpty()) 
      data.put("Test"+i,new Object[{"Test"+i,option_ID,HTMLText,HTMLTextSize});//adding value in HashMap. 
      i++; 
    } 

} 

Я попытался итерации, как показано ниже, я думаю, это не правильный путь:

HashMap<String, Object[]>set=HTMLDocument.createHTMLSet("URL of website"); 
Iterator it = set.entrySet().iterator(); 
while (it.hasNext()) { 
    Map.Entry pair = (Map.Entry)it.next(); 
    System.out.println(pair.getKey() + " = " + pair.getValue()); 
} 

Как я получаю результат, как:

Испытание79 = [Ljava.lang.Object; @ 14e1a0f

Test378 = [Ljava.lang.Object; @ 1a5f880

Как я должен перебрать эту HashMap, чтобы получить Object [] значения, такие как option_id, HTMLText?

+0

Вы должны знать тип объекта итерацию. – Shriram

+1

Значение - * массив * объектов Object. – Maroun

+0

@Shriram: Я создаю этот объект как «новый объект [] {« Test »+ i, option_ID, HTMLText, HTMLTextSize}' где, ID & Text - строка и TextSize имеет тип int. – MKay

ответ

4

Поскольку каждый объект имеет toString() метод, отображается по умолчанию имя класса представления, а затем добавить @ знак, а затем хэш-код, поэтому вы получаете выход

[Ljava.lang.Object;@14e1a0f 

что означает, что массив содержит класс или интерфейс.

Одно решение будет циклически перебираться по массиву и печатать каждую часть (или с использованием метода Arrays.toString), но я настоятельно рекомендую вам обернуть это в свой собственный класс и переопределить метод toString.

+0

Да, это точно сработало. Я попытался принять ваш ответ следующим образом: 'System.out.println (pair.getKey() +" = "+ Arrays.toString ((Object []) pair.getValue()));' Он дал мне содержимое в читаемый формат. – MKay

+0

Кроме того, спасибо за объяснение более раннего вывода. – MKay

+2

@ mk08 Думал, что я действительно рекомендую вам создать собственный класс, содержащий все нужные поля. Это более инкапсулировано и лучше. – Maroun

0

Значение представляет собой массив объекта. Попробуйте следующие вместо

while (it.hasNext()) { 
    Map.Entry pair = (Map.Entry)it.next(); 
     System.out.println(pair.getKey() + " = " + pair.getValue()[0].toString()); 

} 
1

Следующий код может помочь. Всегда лучше создать класс компонента, состоящий из необходимой информации, которая будет храниться в массиве объектов.

package stack.overflow; 

import java.util.HashMap; 
import java.util.Map; 

public class RetrieveMap { 
    public static void main(String[] args) { 
     Person p = new Person(); 
     p.setName("John"); 
     p.setEmpNo("1223"); 
     p.setAge("34"); 

     Person p1 = new Person(); 
     p1.setName("Paul"); 
     p1.setEmpNo("1224"); 
     p1.setAge("35"); 

     Person[] arr = new Person[2]; 
     arr[0] = p ; 
     arr[1] = p1; 

     HashMap<String,Person[]> map = new HashMap<String,Person[]>(); 
     map.put("a1", arr); 

     for(Map.Entry<String, Person[]> entry : map.entrySet()) { 
      System.out.println("Key:" +entry.getKey()); 
      System.out.println("Value:" +entry.getValue()); 
      for(int i=0;i<entry.getValue().length;i++) { 
       System.out.println("------------------"); 
       System.out.println("Array:"+i); 
       Person r1 = (Person)entry.getValue()[i]; 
       System.out.println("Name:" +r1.getName()); 
       System.out.println("Age:" + r1.getAge()); 
       System.out.println("Emp no:" + r1.getEmpNo()); 
       System.out.println("------------------"); 
      } 
     } 
    } 
} 

package stack.overflow; 

public class Person { 
    String name; 
    String age; 
    String empNo; 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getAge() { 
     return age; 
    } 
    public void setAge(String age) { 
     this.age = age; 
    } 
    public String getEmpNo() { 
     return empNo; 
    } 
    public void setEmpNo(String empNo) { 
     this.empNo = empNo; 
    } 
} 
+0

Спасибо за подробный пример. Постараюсь принять его согласно моему требованию. – MKay

1

Короткий ответ - ваш код ведет себя правильно; когда вы вызываете .toString() на Object[] (что происходит неявно с System.out.println()), вы получаете эту нечетную строку [<TYPE>@<IDENTIFIER>. Для печати содержимого массива используйте Arrays.toString().

Есть много вещей, которые мы можем очистить с помощью этого кода.

  • Избегайте смешивания генераторов и массивов (Эффективный Java-элемент 25); в массивах отсутствует тип обеспечения безопасности безопасности, и редко есть веская причина использовать их в современном общем коде. Лучшей сигнатурой типа будет HashMap<String, List<Object>>. Это фактически идентично, но на практике гораздо проще работать.
  • Не используйте массивы для хранения различных типов. Кажется, что вы храните строку "Test", строку идентификатора, текст элемента и длину текста в виде полей в массиве. Это объекты для.Определите объект с этими четырьмя полями и передайте их в конструктор. Еще лучше, поскольку все, кроме i, можно вычислить из элемента, просто передать элемент в конструктор и вычислить необходимую информацию (длину HTML, длину и т. Д.) В конструкторе или даже в классе «getters».
  • Не используйте необработанные типы (эффективный Java Item 23) для Iterator s и Map.Entry s. Ваша IDE может предупредить вас, когда вы используете необработанные типы, чтобы избежать этой общей ошибки программирования. В своем коде вы должны использовать Iterator<Entry<String, Object[]>> и Entry<String, Object[]>
  • Не используйте Iterator в петлю над элементами а Map «s, используйте для каждого-цикла:

    for (Entry<String, ...> e : map.entrySet()) { 
        ... 
    } 
    
  • Не называть Map переменными а set ; они разные. Аналогично, Map.Entry не является pair - он представляет собой отношение ключевого значения.

Вот очищен до версии кода, предполагая Container объект существует, который принимает Element и извлекает данные, необходимые.

doc = Jsoup.connect(url).get(); 
for (org.jsoup.nodes.Element element : doc.getAllElements()) { 
    for (Attribute attribute : element.attributes()) { 
    Container c = new Container(i++, attribute); 
    data.put(c.getKey(), c); 
    } 
} 

И:

HashMap<String, Container> map = HTMLDocument.createHTMLMap("URL of website"); 
for (Entry<String, Container> e : map.entrySet()) { 
    System.out.println(e.getKey() + " = " + e.getValue()); 
} 
+0

Большое спасибо за подробное объяснение и очищение концепции.! – MKay