【问题标题】:How to retrieve object's contents from a node within a Linked List in java [duplicate]如何从java中的链接列表中的节点检索对象的内容[重复]
【发布时间】:2019-09-14 01:51:27
【问题描述】:

我创建了一个接受字符串和整数的 Person 对象。我创建了一个 Node 类来接收泛型类型作为输入。当我调试时,我可以看到对象被创建和存储,但我的输出只是所说的对象的内存地址。我尝试在 toString() 方法中将对象解析为字符串,但没有运气。我有一种预感,问题在于我声明通用数据类型的方式。 这是我的代码:

类人

public class Person {
   //variables
   private String name;
   private int age;

   // default const.
   public Person() {
      name = " ";
      age = 0;
   }
   // overloaded constructor
   public Person(String name, int age) {
      this.name = name;
      this.age = age;
   }
   // methods
   public void setName(String name) {
      this.name = name;
   }
   public void setAge(int age) {
      this.age = age;
   }
   public String getName() {
      return name;
   }
   public int getAge() {
      return age;
   }
}

类节点

package LinkedList;


public class Node <T> {
   // added parameters for person object
   T p;

   Node nextNode;

   public Node () {

   }
   public Node (T p) {
      this.p = p;

   }

   // parse int data into string to simplify the unit test by not showing node memory locations
   @Override
   public String toString() {
      return p.toString();
   }
}

链表类

package LinkedList;

public class myLinkedList <T>{
   //Nodes
   Node head;
   Node tail;
   int size = 0;

   // Generic method
   public void add (T p){
      Node node = new Node(p);
      if(tail == null){
         head = node;        // if no previous tail the new node is the head
         tail = node;        // if no previous tail the new node is also the tail
      }else {
         tail.nextNode = node;  // adds a node to the end of the list
         tail = node;           // the newest node is set to the tail;
      }
      size ++;
   }

   // Generic search method
   public Node search (T p) {
      //empty list
      if (head == null)
         return null;

      // check if the first node is a match
      if (head.p == p)
         return head;

      // assign node as iterator
      Node node = head;

      // iterate through linked list
      while (node.nextNode != null) {
         // assign the next node as current node
         node = node.nextNode;
         // compare current node's data to data
         if (node.p == p)
            System.out.println(" object found");
         return node;
         //exit when the last node is reached

      }
      return null;
   }

   public Node findPreviousNode (T p) {
      // if the current node has no previous node (it's the head)
      if(head.p == p)
      return new Node();

      Node node = head;
      //go through list looking for desired node and return the one before it
      while(node.nextNode != null) {

         if(node.nextNode.p == p)
         return node;
         // if desired node is not found move onto next node
         node = node.nextNode;

      }
      // returns null for previous node if desired node doesn't exist
      return null;
   }

   public Node delete (T p){

      // node selected to delete, initializes as null for a placeholder
      Node nodeToReturn = null;

      //empty list nothing to return
      if(size == 0)
      return null;

      //list of only one node
      if(size == 1) {
         nodeToReturn = head;
         head = null;
         tail = null;
         size --;
         return nodeToReturn;
      }

      // find and delete last node
      Node nodePrev = findPreviousNode(p);

      if(nodePrev.p == null) {

         head = head.nextNode;
         size --;

      } else if(nodePrev != null) {
         if(tail.p == p) {
            nodePrev.nextNode = null;
            tail = nodePrev;
         } else {

            nodePrev.nextNode = nodePrev.nextNode.nextNode;
         }
         size --;
      }

      return null;

   }

   public void traverse() {
      // checks for empty list and prints out the first node
      if(head != null) {
         Node node = head;
         System.out.print(node);

         // moves from node to node printing until it reaches null as nextNode
         while(node.nextNode != null) {

            node = node.nextNode;
            System.out.print( "  " + node.toString());
         }
      }
   }
}

主类

import java.util.ArrayList;
import LinkedList.*;

public class main {
   public static void main(String[] args) {
      // implement linked list
      System.out.println("\n\n Object Linked list");
      myLinkedList peopleGroup = new myLinkedList();
      peopleGroup.add(new Person("robert", 23));
      System.out.println(peopleGroup.search("robert"));
      peopleGroup.add(mike);
      peopleGroup.add(marie);

      peopleGroup.traverse();
   }
}

输出: (我猜,搜索函数返回 null 的原因相同,是罪魁祸首)。

Object Linked list
null
Person@677327b6  Person@14ae5a5  Person@7f31245a
Process finished with exit code 0

【问题讨论】:

    标签: java oop data-structures nodes singly-linked-list


    【解决方案1】:

    你得到的输出不是内存地址,而是哈希值。

    toString() 的默认实现是ClassName@hashValue

    现在您将覆盖 Node 类中的 toString() 以返回 Person.toString() 的值,这仍然是默认实现。

    因此,如果您现在在 Person 类中覆盖 toString(),您就可以开始了。

    【讨论】:

      【解决方案2】:

      如果你想要更有意义的字符串,你需要在你的 Person 类中重写 toString。

      【讨论】:

      • 好的,所以将 toString() 添加到 person 类而不是在 Node 类中?或者除了(在两个类中都有它)。
      【解决方案3】:

      在你的代码中你有几个问题:

      对于匹配,您不应依赖toString 方法。

      search 方法中,您将输入作为String(名称)传递。并且要将其视为匹配项,您有条件,例如 (head.p == p)if (node.p == p),其中 Node 是泛型类型(编译类型),但从技术上讲,它在运行时是 Person 对象。所以在这里你比较String with Person Object。这永远不会给你一个匹配。

      如果你想匹配它,你需要覆盖Person类的equals方法以及hashcode。如下:

      public boolean equals(Object obj) 
      {
        if (this == obj) return true;
          if (obj == null) return false;
          if (this.getClass() != obj.getClass()) return false;
          Person that = (Person) obj;
          if (this.age != that.getAge()) return false;
          if (!this.name.equals(that.getName())) return false;
          return true;
      }
      
      @Override
          public int hashCode() {
              int result = 17;
      
              result = 31 * result + name.hashCode();
              result = 31 * result + age;
              return result;
          }
      

      您可以根据您的要求和搜索条件覆盖这些方法。但与此同时,您需要更改 search 方法中的代码,如下所示:

      // Generic search method
         public Node search (T p) {
            //empty list
            if (head == null)
               return null;
      
            // check if the first node is a match
            if (head.p.equals(p))
               return head;
      
            // assign node as iterator
            Node node = head;
      
            // iterate through linked list
            while (node.nextNode != null) {
               // assign the next node as current node
               node = node.nextNode;
               // compare current node's data to data
               if (node.p.equals(p))
                  System.out.println(" object found");
               return node;
               //exit when the last node is reached
      
            }
            return null;
         }
      

      当您从搜索中传递 Person 时,您需要传递 Person 对象,如下所示:

      peopleGroup.search(new Person("robert", 23));
      

      因此,在进行这些更改后,您将获得类似(跳过添加迈克和玛丽)的结果:

      Object Linked list
      
      test.file1.Person@518532a6
      
      test.file1.Person@518532a6  test.file1.Person@6319ab2  test.file1.Person@bf8ccc2e
      

      【讨论】:

      • 谢谢。在您发表评论后,我确实注意到我传递的是一个字符串,而不是传递一个对象的名称来搜索。我将搜索调用更改为仅传入对象的名称 ex。 System.out.println(peopleGroup.search(robert));
      • 所以现在,你会得到正确的结果。
      猜你喜欢
      • 1970-01-01
      • 2020-06-12
      • 1970-01-01
      • 2019-01-01
      • 2021-12-08
      • 2014-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多