Java 将数组转换为 LinkedList

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19532307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:04:58  来源:igfitidea点击:

Converting an array into a LinkedList

javasingly-linked-list

提问by Clinton Jooooones

I have an array of characters and I'm trying to convert each character into a node that links to the next node in line. The problem is I keep getting caught in infinite loops and I have no idea why. Here's my code:

我有一个字符数组,我正在尝试将每个字符转换为一个节点,该节点链接到下一个节点。问题是我一直陷入无限循环,我不知道为什么。这是我的代码:

String map = "ABBACBCCA";
char[] charArray = map.toCharArray();
ListNode head;
ListNode temp;
ListNode next;

for (int i = 0; i < charArray.length - 1; i++) {
     temp = new ListNode(charArray[i]);
     next = new ListNode(charArray[i+1]);
     temp.next = next;

     if (i == 0) {
          head = temp;
     }
}

And the ListNode class looks like:

ListNode 类看起来像:

class ListNode<T> {
     public T data = null;
     public ListNode next = null;

     public ListNode(T data) {
          this.data = data;
     }
}

It looks like it gets to the last iteration of the for loop and then gets caught in an infinite loop.. Anyone know why?

看起来它到达了 for 循环的最后一次迭代,然后陷入了一个无限循环......有人知道为什么吗?

回答by Jason McD

For starts I would think you would want:

首先,我认为你会想要:

next = new ListNode(charArray[i]);

to be

成为

next = new ListNode(charArray[i+1]);

Something else I noticed:

我注意到的另一件事:

for (int i = 0; i < charArray.length - 1; i++) {
     temp = new ListNode(charArray[i]);
     next = new ListNode(charArray[i+1]);
     temp.next = next;

          if (i == 0) {
            head = temp;
           }
     }

I don't think this is going to yield what you want. It will not give you A->B->B->A etc etc. more over it would give -> A->B, B->B etc etc. Not sure if that's what you are after.

我不认为这会产生你想要的。它不会给你 A->B->B->A 等等,更多的是它会给 -> A->B、B->B 等等。不确定这是否是你所追求的。

More over I think this should get ya good:

更重要的是,我认为这应该会很好:

String map = "ABBACBCCA";
        ListNode<Character> head = null;
        ListNode<Character> newHead = null;
        ListNode<Character> next = null;

        char[] charArray = map.toCharArray();

        head = newHead = new ListNode<Character>(charArray[0]);
        for (int i = 1; i < charArray.length - 1; i++) {
            next = new ListNode<Character>(charArray[i]);

            newHead.next = next;

            newHead = next;
        }

Basically create and link and create and link. (tested out fine for me) Incoming ugly!

基本上是创建和链接以及创建和链接。(对我来说很好)传入丑陋!

System.out.println(head.data);
        ListNode<Character> nextptr = head.next;
        while (true) {

            if (nextptr.next == null) {
                break;
            }
            System.out.println(nextptr.data);
            nextptr = nextptr.next;
        }

回答by Barun

Using the debugger is your best bet, if you want to continue developing your own code. You should probably create some public methods to set the next element of LinkList nodes like I have done in this example. Explaining would be lengthy, so here's the code.

如果您想继续开发自己的代码,使用调试器是最好的选择。您可能应该创建一些公共方法来设置 LinkList 节点的下一个元素,就像我在本示例中所做的那样。解释会很长,所以这是代码。

public class Test {

 public static void main(String[] args) {
    ListNode<Character> head = new Test().arrayToLinkList();

    while ((head = head.nextNode()) != null) {
        System.out.println(head.readData());
    }
 }

 public ListNode<Character> arrayToLinkList() {
    String map = "ABBACBCCA";
    char[] charArray = map.toCharArray();
    ListNode<Character> head, next;
    head = new ListNode<Character>(charArray[0]);
    next = head;
    for (int i = 0; i < charArray.length - 1; i++) {
        next = next.next(new ListNode<Character>(charArray[i + 1]));
    }
    return head;
 }
}

class ListNode<T> {
 private T data = null;
 private ListNode<T> next = null;

 public ListNode(T data) {
    this.data = data;
 }

 public ListNode<T> next(ListNode<T> next) {
    this.next = next;
    return this.next;
 }

 public ListNode<T> nextNode() {
    return this.next;
 }

 public T readData() {
    return data;
 }
}

回答by Chinmay

Your reference variables temp & next are assigned to new Objects during each iteration and you loose track of your next pointers. You could have figured out this problem using debugger as others suggested. Here is the working example.

在每次迭代期间,您的引用变量 temp 和 next 都会分配给新对象,并且您无法跟踪下一个指针。您可以按照其他人的建议使用调试器解决此问题。这是工作示例。

public class Test {

    public static void main(String args[]) {
        String map = "ABBACBCCA";
        char[] charArray = map.toCharArray();
        ListNode<Character> head = null, temp = null;
        for (int i = 0; i < charArray.length; i++) {
            ListNode<Character> obj = new ListNode<Character>(charArray[i]);
            if (temp != null) {
                temp.next = obj;
            } else {
                head = obj;
            }
            temp = obj;
        }
        // Print the list
        while (head != null) {
             System.out.println(head.data);
             head = head.next;
        }
    }
}

class ListNode<T> {
    public T data = null;
    public ListNode<T> next;
    public ListNode(T data) {
        this.data = data;
        this.next = null;
    }
}

回答by YoYo

This is probably one of the simpler ways to build your linked list:

这可能是构建链表的更简单方法之一:

String map = "ABBACBCCA";

ListNode<Character> head = null;
ListNode<Character> tail = null;

for (char c:map.toCharArray()) {
  final ListNode<Character> node = new ListNode<>(c);
  if (head == null) {
    head = node;
  } else {
    tail.next = node;
  }
  tail = node;
}

While taking care of your type parameters everywhere

同时在任何地方照顾您的类型参数

class ListNode<T> {
  public T data = null;
  ListNode<T> next = null;

  public ListNode(T data) {
    this.data = data;
  }
}

Not to mention that you can fully leverage Java api'sas well:

更不用说您也可以充分利用Java api

LinkedList<Character> ll =
  "ABBACBCCA".chars()
    .mapToObj(i->(char)i) // takes care of boxing char
    .collect(Collectors.toCollection(LinkedList<Character>::new));

Also to loop through your ListNode's, you could consider adding:

另外要遍历您的ListNode's,您可以考虑添加:

class ListNodeIterator<T> implements Iterator<T> {
  private ListNode<T> current;

  public ListNodeIterator<T> ListNodeIterator(ListNode<T> node) {
    current = node;
  }

  public boolean hasNext() {
    return current.next != null;
  }

  public T next() {
    current = current.next;
    return current.data;
  }
}

With following modification:

有以下修改:

class ListNode<T> implements Iterable<T> {
  public T data = null;
  public ListNode<T> next = null;

  public ListNode(T data) {
    this.data = data;
  }

  public Iterator<T> iterator() {
    return new ListNodeIterator<>(this);
  }
}

So you can use it as follows:

因此,您可以按如下方式使用它:

for (char c:head) {
  System.out.println("Character: "+c);
}

or even

甚至

head.forEach(c->{System.out.println("Character: "+c);});

Well ... wasn't that a nice trip through Javaland?

嗯……那不是一次穿越爪哇的愉快之旅吗?