Java:用ArrayList写pojo最高效的方法
Java: The most efficient way to write pojo with ArrayList
在时间和内存消耗方面,编写包含 ArrayList 的简单 pojo class 最正确 and/or 最有效的方法是什么? (关于引用的 java 机制,通过 ref' 传递,赋值等):
public class MyClass {
//1. Do we need to initialize here?
public List<String> mList = new ArrayList<>();
//2. Do we need to declare D. Constructor?
public MyClass() {}
//3. Need to initialize the list here or just pass?
public MyClass(List<String> list) {
this.mList = list;
}
//4. Better way for copy/assignment?
public void setMlist(List<String> list) {
this.mList = list;
}
public List<String> getMList() {
return this.mList;
}
}
- Do we need to initialize here?
不,只在需要时才初始化它。如果有可能在未初始化的情况下使用它,请务必检查 null。
- Do we need to declare D. Constructor?
如果你什么都不做,我真的不明白拥有它的意义。请注意,有些人更喜欢仍然声明它在其中写评论并指示它不应该做任何事情:
public MyClass(){
//NOP
}
参见NOP。这不会改变与内存使用相关的任何内容。但是从逻辑上讲,默认构造函数应该初始化列表而不是在开始时初始化它。所以我们有两个选择,我们传递一个已经存在的(使用参数化构造函数)或者我们使用默认构造函数并创建一个空列表。
- Need to initialize the list here or just pass?
通过,否则接收它作为参数有什么意义?如果您对其进行初始化并重新分配,那将毫无意义。您可能需要检查接收到的是否为空,否则对其进行初始化。
- Better way for copy/assignment?
如果你真的想制作副本,你可能需要检查 Collections#copy
。然而,这不是setter的重点,你在这里所做的是正确的。
如果不了解您的意图,这是不可能回答的。即使在编写 "simple pojo class containing ArrayList" 时,您也必须做出大量的设计决策。这里有 8 个,但还有很多很多。
- 您要将字段设为
public
还是 private
? (可能 private
。)
- 如果
private
,是否要提供get
方法?
- 你想提供一个
set
方法,还是希望字段在构造函数中一劳永逸地初始化?
- 你的构造函数 and/or
set
方法的参数应该只接受 List<String>
还是你会允许更通用的东西,比如 Collection<? extends CharSequence>
?
- 您希望使用您的 class 的人能够修改
mList
吗? (这不同于重新分配 mList
。)
- 你想写子classes,还是你想把class写成
final
?
- 如果你想写子classes,你想做任何方法吗
final
?
- 你想提供一个没有参数的构造函数来将
ArrayList
初始化为合理的默认值吗?
这些问题中最微妙的一个是第 5 个问题。假设有人这样做
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
myClass.setMList(list);
然后再这样做
System.out.println(myClass.getMList());
他们可能希望看到 [a, b, c]
,但这可能不会发生,因为可以在两者之间修改 myClass
的内部结构。例如:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
myClass.setMList(list);
list.remove(1); // Modifies the List stored by myClass
System.out.println(myClass.getMList()); // prints [a, c]
如果你不希望这种事情成为可能,你将不得不编写一个 class 在构造函数中复制 List
个对象,setter 和 getter。这将对性能产生影响(但对于小列表来说会很小)。
没有正确或错误的答案。您需要仔细考虑谁在使用 class、他们为什么需要它,并在回答上述所有问题时权衡所有相关因素。
在时间和内存消耗方面,编写包含 ArrayList 的简单 pojo class 最正确 and/or 最有效的方法是什么? (关于引用的 java 机制,通过 ref' 传递,赋值等):
public class MyClass {
//1. Do we need to initialize here?
public List<String> mList = new ArrayList<>();
//2. Do we need to declare D. Constructor?
public MyClass() {}
//3. Need to initialize the list here or just pass?
public MyClass(List<String> list) {
this.mList = list;
}
//4. Better way for copy/assignment?
public void setMlist(List<String> list) {
this.mList = list;
}
public List<String> getMList() {
return this.mList;
}
}
- Do we need to initialize here?
不,只在需要时才初始化它。如果有可能在未初始化的情况下使用它,请务必检查 null。
- Do we need to declare D. Constructor?
如果你什么都不做,我真的不明白拥有它的意义。请注意,有些人更喜欢仍然声明它在其中写评论并指示它不应该做任何事情:
public MyClass(){
//NOP
}
参见NOP。这不会改变与内存使用相关的任何内容。但是从逻辑上讲,默认构造函数应该初始化列表而不是在开始时初始化它。所以我们有两个选择,我们传递一个已经存在的(使用参数化构造函数)或者我们使用默认构造函数并创建一个空列表。
- Need to initialize the list here or just pass?
通过,否则接收它作为参数有什么意义?如果您对其进行初始化并重新分配,那将毫无意义。您可能需要检查接收到的是否为空,否则对其进行初始化。
- Better way for copy/assignment?
如果你真的想制作副本,你可能需要检查 Collections#copy
。然而,这不是setter的重点,你在这里所做的是正确的。
如果不了解您的意图,这是不可能回答的。即使在编写 "simple pojo class containing ArrayList" 时,您也必须做出大量的设计决策。这里有 8 个,但还有很多很多。
- 您要将字段设为
public
还是private
? (可能private
。) - 如果
private
,是否要提供get
方法? - 你想提供一个
set
方法,还是希望字段在构造函数中一劳永逸地初始化? - 你的构造函数 and/or
set
方法的参数应该只接受List<String>
还是你会允许更通用的东西,比如Collection<? extends CharSequence>
? - 您希望使用您的 class 的人能够修改
mList
吗? (这不同于重新分配mList
。) - 你想写子classes,还是你想把class写成
final
? - 如果你想写子classes,你想做任何方法吗
final
? - 你想提供一个没有参数的构造函数来将
ArrayList
初始化为合理的默认值吗?
这些问题中最微妙的一个是第 5 个问题。假设有人这样做
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
myClass.setMList(list);
然后再这样做
System.out.println(myClass.getMList());
他们可能希望看到 [a, b, c]
,但这可能不会发生,因为可以在两者之间修改 myClass
的内部结构。例如:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
myClass.setMList(list);
list.remove(1); // Modifies the List stored by myClass
System.out.println(myClass.getMList()); // prints [a, c]
如果你不希望这种事情成为可能,你将不得不编写一个 class 在构造函数中复制 List
个对象,setter 和 getter。这将对性能产生影响(但对于小列表来说会很小)。
没有正确或错误的答案。您需要仔细考虑谁在使用 class、他们为什么需要它,并在回答上述所有问题时权衡所有相关因素。