简体   繁体   中英

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 ?

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.

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

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 Iterator s and Map.Entry s. 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());
}

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM