MKay
MKay

Reputation: 836

Get array elements from HashMap in Java

I have a method that puts value in HashMap of type HashMap<String, Object[]> & returns the same HashMap.

Code for putting value in 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++;
    }

 }

I tried iterating as below, which I think is not the correct way :

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());
}

As I am getting output as :

Test79 = [Ljava.lang.Object;@14e1a0f

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

How should I iterate over this HashMap to get Object[] values such as option_ID, HTMLText?

Upvotes: 2

Views: 8934

Answers (4)

dimo414
dimo414

Reputation: 48884

The short answer is your code is behaving exactly correctly; when you call .toString() on an Object[] (which happens implicitly with System.out.println()) you get that odd [<TYPE>@<IDENTIFIER> string. To print the contents of an array, use Arrays.toString().

There are a number of things we can clean up with this code, though.

  • Avoid mixing generics and arrays (Effective Java Item 25); arrays lack the type safety generics provide, and there's rarely a good reason to use them in modern generic code. A better type signature would be HashMap<String, List<Object>>. This is effectively identical, but in practice much easier to work with.
  • Don't use arrays to store different types. You appear to be storing a "Test" string, a identifier string, the element's text, and the text's length as fields in an array. This is what objects are for. Define an object with those four fields, and pass them into the constructor. Even better, since everything but i is computable from the element, just pass the element into the constructor and compute the information you need (HTML string, length, etc.) in the constructor or even in the class' getters.
  • Don't use raw types (Effective Java Item 23) for Iterators and Map.Entrys. Your IDE can warn you when you use raw types so you avoid this common programming error. In your code you should use Iterator<Entry<String, Object[]>> and Entry<String, Object[]>
  • Don't use Iterator to loop over a Map's elements, use a for-each loop:

    for (Entry<String, ...> e : map.entrySet()) {
      ...
    }
    
  • Don't call a Map variable a set; they're different things. Similarly a Map.Entry is not a pair - it specifically represents a key-value relationship.

Here's a cleaned-up version of your code, assuming a Container object exists that takes an Element and extracts the data you need.

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);
  }
}

And:

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

Upvotes: 1

Priya
Priya

Reputation: 81

The following code might help. Its always better to create a bean class consisting of the necessary information to be stored in an array of objects.

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;
    }
}

Upvotes: 1

Maroun
Maroun

Reputation: 96016

Since each object has toString() method, the default displays the class name representation, then adding @ sign and then the hashcode, that's why you're getting the output

[Ljava.lang.Object;@14e1a0f

that means the array contains a class or interface.

One solution would be looping on the array and print each part (or using Arrays.toString method), but I highly recommend you wrapping this to your own class and override the toString method.

Upvotes: 4

Amol Patil
Amol Patil

Reputation: 1005

The value is array of Object. Try following instead

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

}

Upvotes: 0

Related Questions