V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
user0506
V2EX  ›  程序员

Java 小白求教,这里变量没有被赋值为什么会变?

  •  1
     
  •   user0506 · 2019-05-07 18:57:49 +08:00 · 1702 次点击
    这是一个创建于 2038 天前的主题,其中的信息可能已经有所发展或是发生改变。

    重新实现了简单的 LinkedList,关键逻辑如下: public void reverse()中调用了 first.reverse(),而 reverse 中并没有对变量 last 做任何操作啊,只是对 first 做了修改,最后调试发现最后一次执行完 this.next = newNext;这一行(53 行)的时候,last 的值就会改变。我看来 last 作为一个独立的变量怎么不应该被 this 影响到啊,想了一下午也没搞明白,求教,感谢送上。

    下面是完整代码,问题只和两个 reverse 方法有关。

    public interface List<T> {
        void add(T value);
        T get(int index);
        int size();
        T remove(int index);
        void reverse();
    }
    
    public class LinkedList<T> implements List<T> {
    
        private LLNode first, last;
    
        class LLNode {
            T value;
            LLNode next;
    
            LLNode(T value, LLNode next) {
                this.value = value;
                this.next = next;
            }
    
            T getLL(int index) {
                if (index == 0) {
                    return value;
                } else {
                    if (next == null) {
                        throw new IndexOutOfBoundsException("error");
                    }
                    return next.getLL(index - 1);
                }
            }
    
            T removeLL(int index) {
                if (next == null) {
                    throw new IndexOutOfBoundsException("error");
                }
                if (index == 1) {
                    T value = next.value;
                    next = next.next;
                    return value;
                } else if (index > 1) {
                    return next.removeLL(index - 1);
                } else {
                    throw new IndexOutOfBoundsException("error");
                }
            }
    
            void reverse(LLNode newNext) {
                if (next != null) {
                    next.reverse(this);
                }
                this.next = newNext;
            }
        }
    
        @Override
        public void add(T value) {
            LLNode newNode = new LLNode(value, null);
            if (first == null) {
                first = last = newNode;
            } else {
                last.next = newNode;
                last = newNode;
            }
        }
    
        @Override
        public T get(int index) {
            if (first == null) {
                throw new IndexOutOfBoundsException("error");
            }
            return first.getLL(index);
        }
    
        @Override
        public T remove(int index) {
            if (first == null) {
                throw new IndexOutOfBoundsException("error");
            }
            if (index == 0) {
                T value = first.value;
                first = first.next;
                return value;
            }
            return first.removeLL(index);
        }
    
        @Override
        public void reverse() {
            if (first == null) {
                return;
            }
            first.reverse(null);
            LLNode tmp = last; //不明白这里 first.reverse 没有给 last 赋值,按理说这里
            //last 的 next=null,但是为什么会是一个 next 等于 value=17 的 LLNode 类型数据呢
            last = first;
            first = tmp;
        }
    
        public static void main(String[] args) {
            List<Integer> list = new LinkedList<>();
            list.add(17);
            list.add(34);
            list.reverse();
        }
    }
    
    3 条回复    2019-05-07 21:08:24 +08:00
    chenluo0429
        1
    chenluo0429  
       2019-05-07 19:08:50 +08:00   ❤️ 1
    主要是要理解 LLNode 的 reverse()方法。
    它从当前节点开始,将后面所有的节点顺序反转了。
    ```
    void reverse(LLNode newNext) {
    if (next != null) {
    next.reverse(this);
    }
    this.next = newNext;
    }
    user0506
        2
    user0506  
    OP
       2019-05-07 20:20:39 +08:00
    @chenluo0429

    我是这么理解的:
    最初传入参数 newNext 为 null,第一次调用
    next.reverse(17) ->17 下一个是 34,那么就变成了 34.reverse(17) -> 34.next=null, -> 再往后不满足 if 就结束了
    17.next=null 有 34.next=17

    所以变成了 34->指向 17->指向 null,因为调用的是 first.reverse(null),所以 first 变成了 value=34 next=17,last 不受影响

    无论如何代码跟变量 last 也没什么关系啊,last 的初始值在被 add()动过后就不变了啊,应该还是 value=34, next=null,为什么执行完最后一次 this.next = newNext 后 last 的值就变了呢?

    我觉得 reverse 反转的是节点的 next 值,但是 last 作为一个独立被赋值的变量,不应该受影响啊,真心求教。
    user0506
        3
    user0506  
    OP
       2019-05-07 21:08:24 +08:00
    @chenluo0429 我好像明白了,原来 last 里保存的不是值而是地址啊,这也就是为什么 reverse 修改了 node 的值的时候 last 变量跟着一起变了,我理解的对吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5873 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 02:38 · PVG 10:38 · LAX 18:38 · JFK 21:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.