考虑到我有一个方法可以将List作为参数传递。在这个方法中,我想在该列表中使用例如ArrayList特定的函数(比如trimToSize())。处理这样的问题的一般方法是什么?
这里有两个例子:
第一种方法(我认为这不好)
private void doSomething(final List<T> list) {
// ... do something
((ArrayList<T>) list).trimToSize();
// ... do something
}
第二种方法(我觉得这个更好)
private void doSomething2(final List<T> list) {
final List<T> myList = new ArrayList<T>();
// Collections.copy(myList, list); or
myList.addAll(list);
((ArrayList<T>) myList).trimToSize();
//..do something
}
我很好奇这是什么问题的最佳解决方案。
答案 0 :(得分:12)
嗯,首选方法是首先编写方法以获取ArrayList
。如果您需要ArrayList
特定功能,则该方法无法使用List
。将确保参数属于正确类型的责任转移给调用者,并且不要在方法内乱搞它。
答案 1 :(得分:6)
如果只想将ArrayList作为参数,为什么不将方法声明为private void doSomething(final ArrayList<T> list)
?
答案 2 :(得分:3)
如果你接受任何实现List接口的对象,那么你的函数应该只调用从接口实现的方法。
如果要从ArrayList类调用函数,则将ArrayList作为参数。比任何一种选择都安全得多。
答案 3 :(得分:2)
第二个我们有大量列表的巨额开销,但更安全。我会去第一个,但检查提供的List是否是ArrayList,然后进行转换。
你应该有充分的理由不把ArrayList作为参数。
答案 4 :(得分:2)
您展示的第一个选项仅适用于ArrayLists
,因此如果您想支持任何类型的List
,则不能选择此选项。如果您想支持任何类型的List
,您必须将其转换(而非转换)为ArrayList
。
我认为可能存在一些混淆,因为List
和ArrayList
密切相关(通过继承)。只有巧合的是,参数类型和我们需要调用函数的类以这种方式相关。
如果我们抽象一下要求:
如果值是以数组形式出现的话,那么用数组中的值创建一个新的ArrayList
然后使用 trimToSize()就没有问题了,因为是一个选择。我们需要的方法 trimToSize()恰好位于List
的子类上,并且作者想要将值作为List
传递。 / p>
答案 5 :(得分:2)
怎么样?
private void doSomething(final List<T> list) {
final ArrayList<T> arrayList;
if (list instanceof ArrayList) {
arrayList = (ArrayList<T>) list;
} else {
arrayList = new ArrayList<T>(list);
}
...
arrayList.trimToSize();
}
当然,我同意Chinmay Kanchi:对于一个私有方法,接受一个比必要更通用的类型是没有意义的。我的方法只有在修改给定列表没有问题时才可行。
答案 6 :(得分:1)
您的第一个方法会更改传递给方法的List
,而另一个方法则不会。两种方法无法比较。
答案 7 :(得分:0)
由于它是一个私有方法,因此使用List接口的约定并不过分重要。没有公共API受到影响,因此请使用最方便的方法在类中使用。
例如,如果其他5个方法使用可能不同类型的List调用此方法,则使用第二个选项并将转换集中在1方法中(如果愿意,您甚至可以检查类型而不转换)。如果你的类只在内部处理ArrayList,并且你知道它在调用时将会是什么,那么将它声明为ArrayList并让你的生活变得轻松。