【问题标题】:List<Map<String, String>> alternatives (Java)List<Map<String, String>> 替代方案 (Java)
【发布时间】:2015-02-26 11:23:05
【问题描述】:

我是 Java 新手,我正在制作一个用于包装此类数据的结构:

Object:
    name:'Obj1'
    otherAttr:'...'
Object:
    name:'Obj2'
    otherAttr:'...'
Object:
    ...

我知道我可以制作我的自定义“对象”类*,但对于使用内置 java 结构,我使用List&lt;Map&lt;String, String&gt;&gt;。所以,设置新的:

List<Map<String, String>> objects = new ArrayList<Map<String, String>>();
foreach(databaseRow){
    Map<String, String> newObject = new HashMap<String, String>();
    newObject.put('name', '...');
    newObject.put('otherAttr', '...');
    objects.add(newObject);
}

我有两个问题:

1- 如果结构的初始化(作为ArrayListHashMap)是大量Java 结构之间的最佳选择。

2- 如果有一个内置结构并不意味着所有这些初始化(对于 List 和每个 Map)。

谢谢!

(*)澄清:我在我的代码中使用了大量类似的结构,并且我会避免制作大量自定义类。但如果这是最好的方法,那就去做吧!

【问题讨论】:

  • 如果你想让它干净,你真的应该创建你自己的自定义类。是否有任何具体原因需要避免这种情况?
  • 我同意@Haroldo_OK 的观点,但只是为了更清楚地说明这一点:您自己的类将由 Java 集合框架中的数据结构组合。他们只是在使用它们并为您的类型提供语义上更有意义的界面。
  • hmm 只是一个提示,你为什么不自己使用地图结构而不是在它上面创建一个列表
  • @nafas 因为在那之后,我想遍历对象列表,并为每个人做一个动作。我无法弄清楚如何仅使用地图来制作它。
  • @T30 但是为什么是地图而不是自定义类,您可以在其中隐藏实现细节,即封装的全部要点。

标签: java data-structures


【解决方案1】:

如果您的每个对象都只有这两个属性(name 和 otherAttr),您可以创建一个包含字段的类,而不是使用 Map:

public class Data {
    private final String name;
    private final String otherAttr;
    // constructor, getters
}

即使您有更多属性,这样做也可能很有用,因为它为您提供了编译时的安全性——您永远不会拼错一个键。您还可以拥有不同类型的字段,而不仅仅是您必须解析的字符串。

为了使您的代码更有意义,您还可以扩展现有的数据结构,例如:

public class Data extends HashMap<String, String> {
    // extra convenience constructors
}

public class DataList extends ArrayList<Data> {
    // extra convenience constructors
}

关于您使用什么集合的问题,这实际上取决于您需要什么。 ArrayList 通常是一个不错的选择(或线程安全的Vector),除非您经常修改列表的开头,在这种情况下建议使用LinkedListHashMap 具有非常好的性能,但如果您需要排序数据,您可以使用 TreeMap 代替。如果您需要保持插入顺序LinkedHashMap 将是最好的。

【讨论】:

  • 是的,“关键拼写安全”是使用自定义类的真正优势!
  • 我更喜欢enum Attributes { NAME, OTHER_ATTR, …; }
【解决方案2】:

如果结构可能不同,是的,这是正确的方法。

如果每个name 都是唯一的,您可以使用Map&lt;String,String&gt;

如果结构始终相同(nameotherAttr 对),您可以使用 POJO(普通的旧 java 对象),这是一个带有 getter 和 setter 的对象的花哨名称:

 public class MyData {
    private String name;
    private String otherAttr;
    public String getName() {return name;}
    public void setName(String name) {this.name=name;}
    public String getOtherAttr() {return otherAttr;}
    public void setOtherAttr(String otherAttr) {this.otherAttr=otherAttr;}
 }

然后将它们存储在List&lt;MyData&gt;

您可以为MyData 提供构造函数,设置nameotherAttr 的值

 MyData(String name, String otherAttr) {
    this.name=name;
    this.otherAttr=otherAttr
 }

【讨论】:

  • POJOJava Bean 不同。后者有 getter/setter,而前者(一个“普通的旧 java 对象”)可以简单地使用公共字段。
【解决方案3】:

在不质疑您所做工作的本质的情况下,我将直接回答您的问题,说您很可能以正确的方式使用最佳数据结构。

【讨论】:

    【解决方案4】:

    你可以让你自己的类有一个这个对象的列表。

    List&lt;myClass&gt; objects = new ArrayList&lt;myClass&gt;();

    【讨论】:

      【解决方案5】:

      1- 如果结构的初始化(作为 ArrayList 和作为 HashMap)是大量 Java 结构之间的最佳选择。

      不,编写您自己的自定义类来保存数据。封装的全部意义在于隐藏实现细节。

      2- 如果有一个内置结构并不意味着所有这些初始化(对于 List 和每个 Map)。

      如果您编写自己的类,则该类的构造函数可以 处理初始化。这就是构造函数的用途。

      【讨论】:

      • 语义吹毛求疵:您使用 &lt;blockquotes&gt; 表示您自己的单词,使用内联文本表示块引号......
      • @5gon12eder 我格式化答案的方式真的是个问题吗?
      • 如果你有充分的理由这样做,那就去做吧。但总的来说,语义上正确的标记很重要,尤其是允许将来更改布局或支持您可能使用的显示器以外的其他设备。巧合的是,使用有效但传达错误语义的结构正是这个线程的目的(你的答案是正确的反对)。 ;-)
      【解决方案6】:

      这是正确的,但如果你想要更简洁的方法,为什么不创建

      public Class MyData{
         private String name;
         private String attr;  //in case you need multiple attributes, make this as list 
         //setters and getters
      }
      

      然后做

      List<MyData> objects = new ArrayList<MyData>();
      

      【讨论】:

        猜你喜欢
        • 2020-01-26
        • 1970-01-01
        • 1970-01-01
        • 2020-01-27
        • 2018-08-02
        • 2018-09-06
        • 1970-01-01
        • 2016-01-12
        • 2020-03-17
        相关资源
        最近更新 更多