创建DataObject以保存所需的不同类型数据

huangapple go评论113阅读模式
英文:

Create DataObject to hold different types of data as needed

问题

我最近从JavaScript转向了Java代码库,用于自动化框架。当涉及到提供给我们的页面对象方法的数据时,我们通常在JavaScript中使用一个对象,如下所示:

const subscriptionInfo = {
     name : "sub1",
     cost : 3,
     active : true,
}

我想在Java中创建相同的效果,我的解决方案是创建一个DataObject类,该类使用HashMap来存储不同类型的值,一个"DataObject"可以包含这些值。例如:

public class DataObject() {
    public Map<String, String> stringValues;
    public Map<String, Integer> integerValues;
    public Map<String, Boolean> booleanValues;
    // 插入更多Map<String, 任何类型> 变量名;

    public DataObject() {
       stringValues = new HashMap<String, String>();
       integerValues = new HashMap<String, Integer>();
       booleanValues = new HashMap<String, boolean>();
       // 在构造函数中实例化所有的映射
    }

    public void addStringValues(String keyName, String s) {
       stringValues.put(keyName, s);
    }

    public String getStringValues(String keyName) {
       if(stringValues.containsKey(keyName)) {
          return stringValues.get(keyName);
       }
    }
    // 对于其他数据类型,可以创建相同类型的方法
}

我对这种方法的问题是,有时我的"DataObject"可能只需要存储字符串,或者字符串和整数。使用我制定的方法,我会占用未使用的资源来实例化其他类型,这些类型不会被添加到"DataObject"中。因此,我认为更好的方法是以下方式:

private Map<String, Map<String, Object>> objectMap;

public DataObject() {
  objectMap = new HashMap<String, Map<String, Object>>();
}

public void addStringValue(String keyName, String s) {
  if(!objectMap.containsKey("stringValues")) {
     Map<String, String> stringValues = new HashMap<String, String>();
     objectMap.put("stringValues", stringValues);
  }
  objectMap.get("stringValues").put(keyName, s);
}

这样,我可以拥有确保类型安全的方法,并在该objectMap内部使用HashMap来根据正确的类型存储数据。这允许在调用DataObject的添加方法时动态生成HashMap,自动化脚本中的DataObject将仅包含它需要存储的类型。我遇到的问题是objectMap无法支持stringValues映射,因为stringValues的类型是<String, String>。

有没有办法让objectMap存储stringValues映射?

英文:

So i recently went from Javascript to Java codebase for an automation framework, when it comes to data supplied to our page object methods we usually used an object in javascript shown as this:

const subscriptionInfo = {
     name : &quot;sub1&quot;,
     cost : 3,
     active : true,
}

I want create the same effect in Java and my solution was creating a DataObject class that used HashMaps for the various different value Types a "DataObject" could hold. Example:

public class DataObject() {
    public Map&lt;String, String&gt; stringValues;
    public Map&lt;String, Integer&gt; integerValues;
    public Map&lt;String, Boolean&gt; booleanValues;
    // insert more Map&lt;String, whateverType&gt; varname;

    public DataObject() {
       stringValues = new HashMap&lt;String, String&gt;();
       integerValues = new HashMap&lt;String, Integer&gt;();
       booleanValues = new HashMap&lt;String, boolean&gt;();
       // instantiate all maps in the constructor
    }

    public addStringValues(String keyName, String s) {
       stringValues.put(keyName, s);
    }

    public getStringValues(String keyName) {
       if(stringValues.containsKey(keyName) {
          return stringValues.get(keyName);
       }
    }
    // same type of methods for the other data types
}

My problem with this approach is that sometimes my "DataObject" maybe only need to hold Strings, or Strings and Integers. With the approach i made, i am taking up unused resources to instantiate other types that wont be added to the DataObject. So i thought the better approach would be the following:

private Map&lt;String, Map&lt;String, Object&gt;&gt; objectMap;

public DataObject() {
  objectMap = new HashMap&lt;String, Map&lt;String, Object&gt;&gt;();
}

public void addStringValue(String keyName, String s) {
  if(!objectMap.containsKey(&quot;stringValues&quot;)) {
     Map&lt;String, String&gt; stringValues = new HashMap&lt;String, String&gt;();
     objectMap.put(&quot;stringValues&quot;, stringValues);
  }
  objectMap.get(&quot;stringValues&quot;).put(keyName, s);
}

This way i can have methods that will ensure type safety and use HashMaps within this objectMap to store the data according to the correct type, and this allows for the HashMaps to be dynamically generated when the DataObject add methods are called, and the DataObject in the automation scripts will hold only the types it needs to store. The problem I'm encountering is that the objectMap cannot support the stringValues map because stringValues is of type: <String, String>.

Anyway i can get the objectMap to store the stringValues Map?

答案1

得分: 1

不要使用Hashmap,而是使用Java泛型类型:

以下是针对此情况的代码片段:

class DataObject {
    List<DataTypeContainer> dataList;

    public List<DataTypeContainer> getDataList() {
        return dataList;
    }

    public void setDataList(List<DataTypeContainer> dataList) {
        this.dataList = dataList;
    }

    @Override
    public String toString() {
        return "DataObject{" +
                "dataList=" + dataList +
                '}';
    }
}

class DataTypeContainer<T> {
    private String key;
    private T value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public DataTypeContainer(String key, T value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public String toString() {
        return "DataTypeContainer{" +
                "key='" + key + '\'' +
                ", value=" + value +
                '}';
    }
}

主类:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        DataObject dataObject = new DataObject();
        dataObject.setDataList(Arrays.asList(
                new DataTypeContainer<>("name", "sub1"),
                new DataTypeContainer<>("cost", 3),
                new DataTypeContainer<>("active", true))
        );
        System.out.println(dataObject);
    }
}

输出:

DataObject{dataList=[DataTypeContainer{key='name', value=sub1},
DataTypeContainer{key='cost', value=3}, DataTypeContainer{key='active',
value=true}]}
英文:

Instead of using Hashmap, use java generic types:

here is a snippet for this scenario:

class DataObject {
    List&lt;DataTypeContainer&gt; dataList;

    public List&lt;DataTypeContainer&gt; getDataList() {
        return dataList;
    }

    public void setDataList(List&lt;DataTypeContainer&gt; dataList) {
        this.dataList = dataList;
    }

    @Override
    public String toString() {
        return &quot;DataObject{&quot; +
                &quot;dataList=&quot; + dataList +
                &#39;}&#39;;
    }
}

class DataTypeContainer&lt;T&gt; {
    private String key;
    private T value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public DataTypeContainer(String key, T value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public String toString() {
        return &quot;DataTypeContainer{&quot; +
                &quot;key=&#39;&quot; + key + &#39;\&#39;&#39; +
                &quot;, value=&quot; + value +
                &#39;}&#39;;
    }
}

Main class

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        DataObject dataObject = new DataObject();
        dataObject.setDataList(Arrays.asList(
                new DataTypeContainer&lt;&gt;(&quot;name&quot;, &quot;sub1&quot;),
                new DataTypeContainer&lt;&gt;(&quot;cost&quot;, 3),
                new DataTypeContainer&lt;&gt;(&quot;active&quot;, true))
        );
        System.out.println(dataObject);
    }

}

Output :

> DataObject{dataList=[GenericClass{key='name', value=sub1},
> DataTypeContainer{key='cost', value=3}, GenericClass{key='active',
> value=true}]}

huangapple
  • 本文由 发表于 2020年9月18日 08:04:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63947610.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定