简体   繁体   English

从Java中的HashMap获取数组元素

[英]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. 我有一个方法将值放入HashMap HashMap<String, Object[]>类型的HashMap<String, Object[]>并返回相同的HashMap。

Code for putting value in HashMap: 将值放入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 Test79 = [Ljava.lang.Object; @ 14e1a0f

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

How should I iterate over this HashMap to get Object[] values such as option_ID , HTMLText ? 我应该如何遍历此HashMap以获得Object []值,例如option_IDHTMLText

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 由于每个对象都有toString()方法,因此默认显示类名表示形式,然后添加@符号,然后添加哈希码,这就是为什么要获取输出的原因

[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. 一种解决方案是在数组上循环并打印每个部分(或使用Arrays.toString方法),但是我强烈建议您将其包装到自己的类中并覆盖toString方法。

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. 创建一个由必需信息组成的Bean类总是更好,该类将存储在对象数组中。

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. 当您在Object[]上调用.toString()时(与System.out.println()隐式发生),您会得到奇怪的[<TYPE>@<IDENTIFIER>字符串。 To print the contents of an array, use Arrays.toString() . 要打印数组的内容 ,请使用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); 避免混合泛型和数组(有效Java项目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>> . 更好的类型签名是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. 您似乎正在将"Test"字符串,标识符字符串,元素的文本以及文本的长度存储为数组中的字段。 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. 更好的是,由于除i所有内容都可以从该元素计算得出,因此只需将该元素传递到构造函数中,并在构造函数甚至类的getter中计算所需的信息(HTML字符串,长度等)。
  • Don't use raw types (Effective Java Item 23) for Iterator s and Map.Entry s. 不要对IteratorMap.Entry使用原始类型(有效Java项目23)。 Your IDE can warn you when you use raw types so you avoid this common programming error. 使用原始类型时,IDE会警告您,这样可以避免这种常见的编程错误。 In your code you should use Iterator<Entry<String, Object[]>> and Entry<String, Object[]> 在您的代码中,应该使用Iterator<Entry<String, Object[]>>Entry<String, Object[]>
  • Don't use Iterator to loop over a Map 's elements, use a for-each loop: 不要使用Iterator来遍历Map的元素,而应使用for-each循环:

     for (Entry<String, ...> e : map.entrySet()) { ... } 
  • Don't call a Map variable a set ; 不要将Map变量称为set they're different things. 他们是不同的东西。 Similarly a Map.Entry is not a pair - it specifically represents a key-value relationship. 类似地, Map.Entry不是一pair -它专门表示键值关系。

Here's a cleaned-up version of your code, assuming a Container object exists that takes an Element and extracts the data you need. 这是代码的清理版本,假设存在一个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);
  }
}

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. 该值是Object的数组。 Try following instead 尝试改为关注

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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