【问题标题】:How to set random values in generic class如何在泛型类中设置随机值
【发布时间】:2019-03-23 18:40:51
【问题描述】:

我尝试用随机值填充 ArrayList。 Arraylist 可以包含字符串、整数、双精度或字符。创建随机值工作正常,但我的问题是我无法编写我的 insertRandom 方法。它应该插入特定的数据类型(如 double、int 等)。我在下面描述了我希望我的 insertRandom 方法执行的操作。 我收到警告“类型缓冲区中的方法 insert(T) 不适用于参数 (int)。 我用谷歌搜索了它,但没有发现/不明白如何将我的值类型转换为 T 对象,或者如何检查(类似于“instanceof”所做的),我的 ArrayLists 包含哪些数据类型。我已经阅读了人们在构造函数中用作参数的类类型,但我不能更改构造函数的参数列表。

public class Buffer <T> {

private ArrayList<T> list;

    // constructor
    public Buffer (int capacity) {
        this.list = new ArrayList<T>();
    }

    // insert items to buffer
    public void insert (T item) {
        list.add(item);
    }

    // insert random values
    public void insertRandom () {

        check if ArrayList is of type String / Integer / Double

        if (ArrayList is-of-type-String) {
           insert("ThisString");
        }
        if (ArrayList is-of-type-Double) {
            insert(3.4);
        }

}

感谢和最好的问候, 帕特里克

【问题讨论】:

  • 在不确切知道您的分配描述的情况下,如果真正的意图是将 any 对象存储在同一个列表中,这听起来像是对泛型的糟糕分配。那基本上就是ArrayList&lt;Object&gt;,泛型对于这种情况并没有真正的用处。
  • 不可能在 Buffer 的方法中获取 T 的运行时类型,除非您将 Class 实例传递给构造函数并将其存储在字段中。你确定这是作业要求的吗?

标签: java generics arraylist


【解决方案1】:

作为一个选项,您可以向构造函数提供对象的Class,并在insertRandom() 方法中检查此类,例如:

public class Buffer <T> {

    private final Class<T> type;
    private ArrayList<T> list;

    // constructor
    public Buffer (int capacity, Class<T> type) {
        this.list = new ArrayList<T>();
        this.type = type;
    }

    // insert items to buffer
    public void insert (T item) {
        list.add(item);
    }

    // insert random values
    public void insertRandom () {

//      check if ArrayList is of type String / Integer / Double     
        if (type == String.class) {
           insert((T)"ThisString");
        }

        if (type == Double.class) {
            insert((T)Double.valueOf(3.4));
        }
    }
}

【讨论】:

  • 您好帕维尔,感谢您的回答!这是我在网上看到的解决方案之一,但我的问题是我的构造函数的参数列表不允许更改。有没有其他方法可以在不更改构造函数的情况下找出类型?
  • @AtMakeIT,我不太确定您的要求,但显然您知道创建缓冲区时要存储在缓冲区中的对象类型。因此,您可能希望将 insertRandom() 方法移出 Buffer 类,并根据创建它的相同条件填充它。
【解决方案2】:

假设即使你使用了泛型并且 T 是一个 Double,你也无法向它添加一个 String。这意味着没有必要检查类的类型。

Buffer<Double> bd = new Buffer(10);
bd.insert(22.9);
bd.insert("string"); // compiler error

我认为您在这里不需要泛型。您只需要一个Buffer&lt;Object&gt;,因为根据您的要求,您需要添加字符串、整数、双精度或字符。所以你甚至不需要做类型检查。

类似:

Buffer<Object> buff = new Buffer<Object>(10);
buff.insert(22.9);
buff.insert("");
buff.insert(13);

【讨论】:

  • 嗨 Nicholas,不幸的是,我必须使用类“public class Buffer { }”来完成我的作业......我尝试最终得到 3 个不同的 ArrayList,一个只包含整数,一个只包含字符。所以它们不应该混在一起
  • 然后创建您的对象,例如Buffer&lt;Object&gt; bd = new Buffer&lt;Object&gt;(10);。现在您可以在其中添加任何内容,而无需进行任何type检查。
【解决方案3】:

第一点是您不能将int 之类的原语用于ArrayLists。相反,您必须使用相应的类。在这种情况下Integer。 第二点:我认为您可以通过 T.class.equals(Integer.class) 来检查 ArrayList 包含的类型。

【讨论】:

  • 感谢您的回答!对于您的第一点:我以上述方式使用了插入方法,我认为它之所以有效,是因为自动装箱。因为我认为这可能有问题,所以我已经尝试将变量转换为 (Integer) 或 (Double)。到第二点:我刚试过 T.class.equals(Integer.class);但 Eclipse 告诉我“类型参数 T 的非法类文字”
猜你喜欢
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多