自定义数组包装类投射安全性/效率

时间:2016-12-29 23:14:37

标签: java arrays generics casting

我正在编写一个需要通用列表的java应用程序。这个列表需要能够动态且经常地调整大小,显而易见的答案是通用的Linkedlist。不幸的是,它还需要像通过调用索引添加/删除它们一样频繁地获取/设置值。 Arraylist可以很好地解决这个问题。由于这些选项都不是我想要的,所以我创建了自己的通用数组包装类。我已经知道很长一段时间在java中创建一个通用数组是非法的,我已经读过,通常不是使用泛型来定义数组的类型,而是只创建一个object[]数组然后将每个元素单独地转换为正确的类型。这类似于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;
    }
}

这只是该类的基础,但主要思想是,数组包装器的每个特定用法都扩展了empty(int n)方法,返回大小为n E类型的数组希望避免所有昂贵的铸造。使用String作为类型的示例如下。

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];
    }
}

我知道这个实现有效,我不知道是什么

  1. 这样做是否安全?
  2. 我知道转换有点挑剔,因为java内置了很多隐式转换,这实际上是一种解决Arraylist已经执行的所有转换的方法吗? LI>
  3. 将每个元素投射到ArrayList中的正确类型是否更有效/更低效?

2 个答案:

答案 0 :(得分:1)

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

1-如果您需要比调整大小更直接的访问:绝对可以使用ArrayList。
2-如果您需要更多rezising而不是直接访问:您可以使用LinkedList。

我会尝试使用 HashMap ,因为它是一个试图优化直接访问和调整大小的集合,因此可能是您的最佳选择。唯一的区别是您必须使用密钥而不是索引来访问集合中的值,但您仍然可以像使用数组中的int索引一样使用Integer键。一件好事是你可以使用任何类型的物体作为钥匙。

此外,您可以使用 LinkedHashMap ,因为如果您需要这样做,迭代整个集合的速度会更快。

无论如何,我无法向您保证这些是您使用的最佳选择,但我可以向您保证,您将在Java API中找到适当的(已开发的)集合类型。

这就是为什么我建议您阅读有关收藏品的官方文档,您将全面了解这些文件并能够为您的特定问题选择最有效的文件 - &gt; https://www.tutorialspoint.com/java/java_collections.htm

答案 1 :(得分:1)

检查unrolled linked list,这可能就是您所需要的。

接下来,您可能需要考虑通过扩展List来实际实现AbstractList以继续使用集合框架。一个&#34;数组包装器&#34;最终会很麻烦。

接下来,施法可能会有一些开销(见Does Java casting introduce overhead? Why?),但我认为没有什么值得考虑的。您的方法的缺点是您需要在每次使用时实施empty方法。从我的角度来看,这对于可疑的性能改进来说价格太高了。

回答你的问题:

  • 创建子类中实现的数组模板方法是可以的。使用content方法公开此数组的安全性较低。
  • 我不认为你可以摆脱铸造。我也不认为演员表演需要担心。
  • 运行基准并测量它。我认为它会更有效率,因为不需要进行类型检查,但这不会是重要的/明显的。