Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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_List_Types_Nodes - Fatal编程技术网

Java—更改原始类型变量的值。可能的

Java—更改原始类型变量的值。可能的,java,list,types,nodes,Java,List,Types,Nodes,首先,我要说我是一名Java(/编程)新手,这是我在网站上的第一个问题 刚刚学习了如何使用递归节点在Java中创建有序列表。 一切都很简单,直到我进行了这个练习,要求我编写一个方法,将每个节点中包含的值加倍。 以下是我试图编写的代码: public class ListaInteri<E extends Integer> { private NodoLista inizio; // Private inner class each instance of these

首先,我要说我是一名Java(/编程)新手,这是我在网站上的第一个问题

刚刚学习了如何使用递归节点在Java中创建有序列表。 一切都很简单,直到我进行了这个练习,要求我编写一个方法,将每个节点中包含的值加倍。 以下是我试图编写的代码:

public class ListaInteri<E extends Integer>
{
    private NodoLista inizio;

    // Private inner class each instance of these has a raw type variable and a
    // ref
    // to next node in the list
    private class NodoLista
    {
        E dato;
        NodoLista pros;
    }

    // method that adds whatever is meant by x to the begging of the list

    public void aggiungi(E x)
    {
        NodoLista nodo = new NodoLista();
        nodo.dato = x;
        if (inizio != null)
            nodo.pros = inizio;
        inizio = nodo;
    }

    // a method that switches last and first elements in the list
    public void scambia()
    {
        E datoFine;

        if (inizio != null && inizio.pros != null) {
            E datoInizio = inizio.dato;
            NodoLista nl = inizio;

            while (nl.pros != null)
                nl = nl.pros;

            datoFine = nl.dato;
            inizio.dato = datoFine;
            nl.dato = datoInizio;
        }
    }

    // and here is the problem
    // this method is supposed to double the value of the raw type variable dato
    // of each node
    public void raddoppia()
    {

        if (inizio != null) {
            NodoLista temp = inizio;
            while (temp != null) {
                temp.dato *= 2;
            }
        }
    }

    // Overriding toString from object (ignore this)
    public String toString(String separatore)
    {
        String stringa = "";
        if (inizio != null) {
            stringa += inizio.dato.toString();
            for (NodoLista nl = inizio.pros; nl != null; nl = nl.pros) {
                stringa += separatore + nl.dato.toString();
            }
        }
        return stringa;
    }

    public String toString()
    {
        return this.toString(" ");
    }

}
现在请记住,任何形式的帮助都将不胜感激。以下是我想要回答的问题

  • 为什么会发生这种情况?在编译期间,如果忽略了与参数或参数类型有关的所有信息,那么是否存在原始类型的类型擦除
  • 我该如何解决这个问题?第二个方法(第一个和最后一个切换的方法)表明,只要由另一个原始类型传递,编译器就可以更改节点中的字段,而如果我们尝试将它乘以2,例如,它就不再正常了,因为编译器现在知道我们在谈论int/Integer,所以会返回此错误。 提前感谢您的回答
  • 编辑;抱歉,必须使其可读,现在应该可以了。
    编辑2:几乎可以读了啊

    类型擦除不是这里的问题(泛型类型被擦除,因此它们在运行时不可用,但在编译时,类型必须是可转换的)


    我可能会解决这个问题,根本不使用类型参数
    Integer
    是final类,因此没有必要让它使用更通用的类型,例如
    E extends Integer
    Integer
    是final类,不能扩展。因此,使用泛型是毫无意义的(尽管在语法上是有效的),您也可以只使用
    int
    ——然后问题就会消失。

    试试:

      temp.dato= new Integer(((Integer)temp.dato).intValue*2);
    
    我想应该是这样

    <E extends Number>
    

    我认为这可以编译,但如果有人将您的数据结构用于非整数,此方法将不会产生正确的答案。

    一个澄清,只是为了确保您理解一些事情:您问

    难道没有类型这样的东西吗 编译期间删除原始类型 所有信息都要做的时间 具有参数或参数的类型是 忽视

    人们在爪哇讨论了很多关于“类型删除”的问题,部分是因为类型擦除是java和C++之间的许多有趣的区别之一,部分是因为类型擦除会给你带来新的java java代码时,会出现奇怪的和意外的错误。p> 然而,类型擦除并不意味着“所有与参数或参数类型有关的信息都被忽略”——它意味着比这要窄得多的东西。另外,正如您所说,类型擦除是“在编译时”应用的,但它是在编译器检查程序中的所有类型和声明以查看是否存在任何类型错误之后应用的

    第一个问题:什么是类型擦除?类型擦除只发生在泛型类型上
    Integer
    不是泛型类型,但
    ArrayList
    是泛型类型,因为您可以声明
    ArrayList
    ArrayList
    。在编译器检查完程序中的类型以使它们都匹配之后,它会丢弃所有关于泛型类型的信息,这样
    ArrayList
    ArrayList
    都会变成
    ArrayList
    。这就是为什么可以在Java中编写
    if(foo instanceof String)
    ,但不能编写
    if(foo instanceof ArrayList)
    :当运行时对
    if
    语句求值时,无法将
    ArrayList
    ArrayList
    或任何其他类型的
    ArrayList
    区分开来

    第二个问题:何时应用类型擦除?在检查代码是否存在编译错误后,当编译器生成编译代码(“字节码”)时,将应用类型擦除。这意味着,即使Java使用类型擦除,以下代码在Java中也会出现编译错误:

    ArrayList<String> foo = new ArrayList<String>();
    foo.add(new Integer(3)); // Error - Compiler knows that String is expected
    
    ArrayList foo=new ArrayList();
    foo.add(新整数(3));//错误-编译器知道需要该字符串
    
    我知道我还没有回答您的问题,但我想确保您首先理解类型擦除。:-)

    回到最初的问题:为什么需要用
    声明类?这是家庭作业特别要求的吗?我只是将您的代码复制并粘贴到Eclipse中,删除了顶部的
    ,并将所有
    E
    声明替换为
    Integer
    ,它编译得很好


    (顺便说一句,你在这里写的
    raddoppia
    仍然存在问题,即使你去掉
    并将其编译-你找到了吗?试着用一个包含多个元素的列表测试
    raddoppia
    ,你应该会看到问题…

    讨厌格式设置,我喜欢意大利标识符。它发生在编译过程中,因此类文件没有泛型类型的概念,对吗?好的,再次强调一下,我想我明白了你们不使用E整数的意思。问题是,若我并没有弄错的话,你们可以添加任何类型的对象吗?除非我还更改了内部类并重建了列表。无论如何,有没有办法让它只修改“raddoppia”方法?又是thx。ps:抱歉有点固执,如果由我决定的话,我只会使用向量hehe:)这只是一个学校练习,必须以某种方式完成。答案是thx。首先要记住,这是一个很酷的练习,所以他们实际上会尝试去挖掘他们能找到的每个隐藏的小角落,看看是否“你可以这样做”。本例中未扩展第二个整数。这仅仅意味着这个集合只适用于Integer的子类型,所以这就像是说这个集合只能是lista lista lista(或者在comp上停止)
    tmp.dato = tmp.dato.intValue() * 2;
    
    ArrayList<String> foo = new ArrayList<String>();
    foo.add(new Integer(3)); // Error - Compiler knows that String is expected