Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义数组包装器类强制转换安全性/效率_Java_Arrays_Generics_Casting - Fatal编程技术网

Java 自定义数组包装器类强制转换安全性/效率

Java 自定义数组包装器类强制转换安全性/效率,java,arrays,generics,casting,Java,Arrays,Generics,Casting,我正在编写一个需要通用列表的java应用程序。此列表需要能够动态调整大小,并且需要经常调整大小,最明显的答案是使用一个通用的Linkedlist。不幸的是,它还需要像通过调用索引添加/删除值一样频繁地获取/设置值。这可以通过Arraylist很好地解决。因为这两个选项都不是我想要的,所以我创建了自己的通用数组包装类。我早就知道在java中创建泛型数组是非法的,我读到过这样一篇文章,通常不使用泛型来定义数组的类型,而是创建一个对象[]数组,然后将每个元素分别转换为适当的类型。这与Arraylist

我正在编写一个需要通用列表的java应用程序。此列表需要能够动态调整大小,并且需要经常调整大小,最明显的答案是使用一个通用的
Linkedlist
。不幸的是,它还需要像通过调用索引添加/删除值一样频繁地获取/设置值。这可以通过
Arraylist
很好地解决。因为这两个选项都不是我想要的,所以我创建了自己的通用数组包装类。我早就知道在java中创建泛型数组是非法的,我读到过这样一篇文章,通常不使用泛型来定义数组的类型,而是创建一个
对象[]
数组,然后将每个元素分别转换为适当的类型。这与
Arraylist
已经做的类似;然而,我已经读到,在java中,强制转换是一个非常昂贵的操作。因此,为了避免强制转换的必要性,我的自定义包装器类如下所示

public abstract class CustomArrayWrapper<E extends Object>{
    private E[] content;

    public abstract E[] empty(int n);

    public CustomArrayWrapper(){
        this.content = empty(0);
    }

    public CustomArrayWrapper(int n){
        this.content = empty(n);
    }

    public CustomArrayWrapper(E[] content){
        this.content = content;
    }

    public E[] content(){
        return content;
    }
}
我知道这个实现是有效的,但我不知道的是

  • 这样做安全吗?
  • 我知道强制转换有点挑剔,因为java中内置了很多隐式强制转换,这实际上是一种绕过
    Arraylist
    已经执行的所有强制转换的方法吗?
  • 它是否比将每个元素强制转换为
    ArrayList
    中的适当类型更有效

  • 我建议您不要花费精力和时间尝试创建自定义集合类型,因为标准JavaAPI已经有很多这样的集合类型。您将赢得时间,并确保它安全且功能齐全。
    例如,如果您确实需要经常调整大小,也需要经常获取和设置项目,我会选择其中一些:

    1-如果您需要比调整大小更直接的访问权限,请选择ArrayList。
    2-如果您需要比直接访问更多的资源,您可以使用LinkedList

    我会尝试使用HashMap,因为它是一个试图优化直接访问和调整大小的集合,所以可能是您的最佳选择。唯一的区别是,必须使用键而不是索引来访问集合中的值,但仍然可以使用整数键,方法与在数组中使用int索引相同。一件好事是,你也可以使用任何类型的对象作为键

    此外,您还可以使用LinkedHashMap,因为如果需要的话,迭代整个集合会更快

    无论如何,我不能向您保证这些是您可以使用的最佳选项,但我可以向您保证,您将在JavaAPI中找到合适的(已开发的)集合类型

    这就是为什么我建议您阅读有关收藏的官方文档,您将对它们有一个大致的了解,并能够为您的特定问题选择最有效的-->

    检查,这可能是您需要的

    接下来,您可能要考虑通过扩展<代码> ActuditList来实现“<代码>列表< /C>”,以保持与集合框架的一致。“数组包装器”最终将变得很麻烦

    接下来,演员可能会有一些开销(请参阅),但我认为这不值得考虑。这种方法的缺点是每次使用时都需要实现
    empty
    方法。从我的观点来看,这对于有问题的性能改进来说是一个太高的价格

    回答您的问题:

    • 创建在子类中实现的数组模板方法是可以的。不太安全的是在
      content
      方法中公开此数组
    • 我认为你不能摆脱演员的角色。我也不认为演员的表现值得担心
    • 运行基准测试并测量它。我认为这样会更有效率,因为不需要进行类型检查,但这并不是什么显著的事情

    “我读到,在java中,强制转换是一项非常昂贵的操作”-真的吗?你有数字来支持吗?@sisyphus有一些开销,请注意这并不能完全回答问题,但是你可以消除子类中的所有方法声明,只为
    empty
    的具体实现。这是用来做什么的?你需要访问数据数组,而不是对数组索引使用额外的getter方法,并且担心显式强制转换的成本实际上会成为一个问题?@lexicore当然,但是一切都有一些开销。这个问题的前提是,
    ArrayList
    LinkedList
    的表现不够好,而且演员阵容“过于昂贵”。在创建自定义集合实现之前,值得先研究一下这些前提条件。@sisyphus“但是所有内容都有*一些开销”*-这绝对不是真的,不是所有内容都有开销。+1表示不尝试构建自定义集合类。相反,使用现有的类来衡量性能。除了不现实的情况外,LinkedList比ArrayList慢。JDK的人甚至考虑贬低它。调整ArrayList的大小很快。遍历链表的速度很慢。当您需要的是一个列表(即一个有序的、可编辑的集合)时,使用HashMap而不是ArrayList根本不是一个好建议。
    public class StringArrayWrapper extends CustomArrayWrapper<String>{
    
        public StringArrayWrapper(){
            super();
        }
    
        public StringArrayWrapper(int n){
            super(n);
        }
    
        public StringArrayWrapper(String[] content){
            super(content);
        }
    
        public String[] empty(int n){
            return new String[n];
        }
    }