通用链接对象列表(Java)

时间:2013-04-21 03:10:37

标签: java list object generics

我是Java的新手,这是我使用它的第二堂课(在大学里)。在学期开始时,我创建了一个代表Zombies的简单类,其中包含年龄,类型和名称。后来,我制作了一个整数链表。现在,我需要创建一个可以容纳这些“Zombies”的通用链表。我还必须制作一个菜单,允许我添加,删除,计数和显示'Zombies'。我一直在盯着这几个小时,浏览我的书,并在网上寻找我的问题的答案。我可以添加并显示这些'Zombies',但是在列表中计算它们并尝试删除它们只是让它告诉我没有我输入的参数。换句话说,我可能会比较“僵尸”的问题。这是我的代码。我理解这是一个很好的300行代码来查看...但我没有想法。

Zombie.java

public class Zombie
{
private String zAge;
private String zType;
private String zName;

public Zombie(String zA, String zT, String zN)
{
    zAge = zA;
    zType = zT;
    zName = zN;
}

public void setZAge(String zA)
{
    zAge = zA;
}

public void setZType(String zT)
{
    zType = zT;
}

public void setZName(String zN)
{
    zName = zN;
}

public String getZAge()
{
    return zAge;
}

public String getZType()
{
    return zType;
}

public String getZName()
{
    return zName;
}

public boolean equals(Zombie zomb)
{
    if(zomb.getZAge() == zAge && zomb.getZType() == zType && zomb.getZName() == zName)
        return true;
    else
        return false;
}
}

LinkedBag.java

public class LinkedBag<E>
{
//Head node and number of nodes in bag
private Node<E> head;
private int manyNodes;

//Constructor
public LinkedBag()
{
    head = null;
    manyNodes = 0;
}

//Returns the number of nodes in the bag
public int getSize()
{
    return manyNodes;
}

//Returns the node that is at the head of the linked list
public Node<E> getListStart()
{
    return head;
}

//Adds a node to the beginning of the list
public void add(E element)
{
    head = new Node<E>(element,head);       //Creates a new node pointing to the head and sets the head of the linked bag to the new Node
    manyNodes++;        //Increments Node counter
}

//Counts the number of times Node [target] occurs within the bag
public int countOccurences(E target)
{
    int count = 0;      //Initializes incrementable counter

    if(head==null)      //Checks if bag is empty and returns null if bag is empty
        return 0;

    if(head.getData().equals(target))       //Checks if the head of the linked list is [target]
        count++;            //Increments counter

    Node<E> cursor = head;      //Sets temporary Node [cursor] to the same value and pointer as head

    while(cursor.getLink() != null)     //Loops until the next Node contains no value
    {
        if(cursor.getLink().getData().equals(target))           //Checks if the value of the next Node is [target]
            count++;                //Increments counter

        cursor=cursor.getLink();            //Cursor continues down linked list
    }

    return count;       //Returns incremented int [count], number of occurences of [target]
}

//Checks if Node [target] exists within the bag
public boolean exists(E target)
{
    if(head.getData().equals(target))       //Checks if the head of the linked list is [target]
        return true;

    Node<E> cursor = head;      //Sets temporary Node [cursor] to the same value and pointer as head

    while(cursor.getLink() != null)     //Loops until the next Node contains no value
    {
            if(cursor.getData().equals(target))     //Checks if current Node is [target] and returns true if true
                return true;

            cursor=cursor.getLink();        //Cursor continues down linked list
    }
            return false;       //Returns false if cursor goes through entire linked list and [target] isn't found
}

//Checks if Node [target] exists within the bag and removes the first occurence of it
public boolean remove(E target)
{       
    if(head==null)          //Returns false if bag is empty
        return false;

    if(head.getData().equals(target))   //If the head Node's data is [target]
    {
        head = head.getLink();      //Make the next Node the head
        manyNodes--;            //Decrements Node counter
        return true;            //Returns true, found [target]
    }

    Node<E> cursor = head;          //Sets temporary Node [cursor] to the same value and pointer as head

    while(cursor.getLink() != null)     //Loops until the next Node contains no value
    {
        cursor = cursor.getLink();      //Cursor continues down linked list

        if(cursor.getLink().getData().equals(target))   //If the next node's data is [target]
        {
            cursor.setLink(cursor.getLink().getLink());     //Sets current Node's link to the next Node's link, by passing the next Node
            manyNodes--;            //Decrements Node counter
            return true;            //Returns true, found [target]
        }
    }
    return false;           //Returns false, [target] not found
}
}

Node.java

public class Node<E>
{
private E data;
private Node<E> link;


public Node(E initialData, Node<E> initialLink)
{
    data = initialData;
    link = initialLink;
}

public E getData()
{
    return data;
}

public Node<E> getLink ()
{
    return link;
}

public void setData(E element)
{
    data = element;
}

public void setLink(Node<E> newLink)
{
    link = newLink;
}
}

这是用户与之交互的菜单文件 ZombiesProj2.java

import java.util.Scanner;

public class ZombiesProj2
{
public static void main(String[] args) throws InterruptedException
{
    LinkedBag<Zombie> zBag = new LinkedBag<Zombie>();       //Linked bag to hold Zombie Objects
    String choice = "";

    Scanner input = new Scanner(System.in);

    while(!choice.equalsIgnoreCase("x"))
    {   
        //Menu
        System.out.println("\nSac de Zombi\n");
        System.out.println("S - Display size of bag");
        System.out.println("A - Add 'Zombie' to bag");
        System.out.println("R - Remove 'Zombie' from bag");
        System.out.println("F - Find 'Zombie' in bag");
        System.out.println("D - Display contents of bag");
        System.out.println("X - Exit");
        System.out.print("Enter Selection: ");

        //Input and Output
        choice = input.nextLine();

        if(choice.equalsIgnoreCase("s"))
        {
            System.out.println("\nSize = " + zBag.getSize() + "\n");
        }
        else if(choice.equalsIgnoreCase("a"))       //adds zombie
        {
            String zAge;
            String zType;
            String zName;

            System.out.print("How many years has this zombie ROAMED THE EARTH: ");
            zAge = input.nextLine();
            System.out.print("What type of zombie is it: ");
            zType = input.nextLine();
            System.out.print("What would you like to name this zombie: ");
            zName = input.nextLine();

            Zombie newZomb = new Zombie(zAge,zType,zName);
            zBag.add(newZomb);
        }
        else if(choice.equalsIgnoreCase("r"))       //removes zombie
        {
            String zAge;
            String zType;
            String zName;

            System.out.print("How many years has this zombie ROAMED THE EARTH: ");
            zAge = input.nextLine();
            System.out.print("What type of zombie is it: ");
            zType = input.nextLine();
            System.out.print("What is the name of the zombie: ");
            zName = input.nextLine();

            Zombie rZomb = new Zombie(zAge,zType,zName);

            zBag.remove(rZomb);
        }
        else if(choice.equalsIgnoreCase("f"))       //counts number of matching zombies
        {
            String zAge;
            String zType;
            String zName;

            System.out.print("How many years has this zombie ROAMED THE EARTH: ");
            zAge = input.nextLine();
            System.out.print("What type of zombie is it: ");

            zType = input.nextLine();
            System.out.print("What is the name of the zombie: ");
            zName = input.nextLine();

            Zombie fZomb = new Zombie(zAge,zType,zName);

            System.out.println("The " + zAge + " year old zombie type " + zType + " named " + zName + " occurs " + zBag.countOccurences(fZomb)+ " time(s)");
        }
        else if(choice.equalsIgnoreCase("d"))       //displays entire zombie 'bag'
        {
            Node cursor = zBag.getListStart();
            Zombie dZomb;
            while(cursor !=null)
            {
                dZomb = (Zombie)cursor.getData();
                System.out.print("[Zombie "+dZomb.getZAge()+" "+dZomb.getZType()+" "+dZomb.getZName()+"],");
                cursor = cursor.getLink();
            }
        }
        else if(!choice.equalsIgnoreCase("x"))  
        {
            System.out.println("Error: Invalid Entry");
        }
    }
}
}

更新了equals和hashCode

public boolean equals(Object obj)
{
    if(obj==null)
        return false;
    if(obj==this)
        return true;
    if(obj.getClass() != getClass())
        return false;

    Zombie zomb = (Zombie)obj;
    if(zomb.getZAge().equals(zAge) && zomb.getZType().equals(zType) && zomb.getZName().equals(zName))
        return true;
    else
        return false;
}

public int hashCode() { return 0; }

2 个答案:

答案 0 :(得分:3)

我知道,因为您正在尝试学习编程,所以您正在编写自己的linked list,而不是使用Java的LinkedList。但是,有一些事情你错过了。

  1. 您的equals方法应与Object Zombie.equals(Object)中的签名相同。并且,如果参数不是Zombie,它应该做的第一件事就是返回false
  2. 每当你编写一个equals方法时,你还必须编写一个hashCode方法。请查看最详细的任何示例。
  3. 切勿对字符串使用equals运算符。始终使用equals方法。将zomb.getZAge() == zAge替换为zomb.getZAge().equals(zAge)
  4. 为什么zAge为String?你可以把它变成某种数字。
  5. 没有必要在课堂上放置“Z”。它位于Zombie;你的读者知道。在工作中,我有同事坚持在所有变量中重复类名。
  6. 这不是很好的代码。

    public class Document {
        private Long documentId;
        private String documentName;
        private String documentAuthor;
        private Date documentPublicationDate;
        // 10 more instance variables.
        // Constructors, accessors, other code.
    }
    

    然后他们将Document类型的变量命名为documentAdocumentB等。这是多么无聊,重复和多余。

答案 1 :(得分:0)

1)为什么要命名一个包含节点数'manyNodes'而不是'nodeCount'的变量。如果你问一些随机程序员包含了什么名为'manyNodes'的变量,你认为他们能猜到吗?如果你问一些随机程序员变量nodeCount包含什么怎么办?你认为随机程序员甚至可以猜出nodeCount的类型吗?那么'manyNodes'的类型怎么样?

2)尝试这样的事情怎么样:

public void add(Node<E> element)
{
    if (head == null) {
        head = element;
    }
    else {
        tail.nextNode = element;
    }

    tail = element;
    nodeCount++;        //Increments Node counter
}


public class Node<E>
{
    private E data;
    private Node<E> nextNode;
}


public class LinkedBag<E>
{

    private Node<E> head;
    private Node<E> tail;
    private int nodeCount;   
}

//Constructor
public LinkedBag()
{
    head = tail = null;
    nodeCount = 0;
}