【问题标题】:How to compare objects in a generic LinkedList如何比较通用 LinkedList 中的对象
【发布时间】:2014-11-16 01:06:27
【问题描述】:

如何比较通用链表中的对象?我从头开始编写了我的链表。我有一个名为 Country 的类,它从 csv 文件中读取数据,并存储国家名称及其特定年份的蜂窝统计数据。它从 1960 年到 2012 年读取 dat。我的程序运行良好,因为我能够打印出列表。但是当我搜索列表以匹配在控制台中打印出的国家/地区名称时。说没找到。我是泛型的新手,当我试图覆盖 Country 类中的 equals 方法来比较名称时,我觉得有些不对劲。但是我在 Country 类中的 equals 方法没有被调用。我尝试通过放置打印输出语句来调试equals方法以查看它是否被调用过,但它从未被调用过。我的猜测是因为使用了泛型。请我需要一些帮助来解决这个问题。这是我在应用程序中遇到的一个问题,因为我的 contains 方法根本没有比较国家/地区名称。

类链表

public class LinkedList<T> {

private Node<T> first;

public LinkedList()
{
    this.first = null;
}

//returns true if list is empty
public boolean isEmpty()
{
    return (first==null);
}
//adds the node to the end of the list
public void add(T obj)
{
    Node<T> newNode = new Node<T>(obj);
    if(this.isEmpty())
    {
        newNode.setNode(first);
        first = newNode;
    }
    else
    {
        Node<T> current = first;
        while(current.getNext()!=null)
        {
            current = current.getNext();
        }
        current.setNode(newNode);
    }
}

public String toString()
{
    String result ="";
    if(this.isEmpty())
    {
        result += "Cannot print an empty list";
        return result;
    }
    else
    {
        Node<T> current = first;
        while(current!=null)
        {
            result +=current.getObj();
            current = current.getNext();
        }
        return result;
    }
}
//searches for the countryName and returns the country if found
public T contains(T obj)
{
    if(this.isEmpty())
    {
        return null;
    }
    else
    {
        Node<T> current = first;
        while(current!=null)
        {
            if(current.getObj().equals(obj))
            {
                return current.getObj();
            }
            current= current.getNext();
        }
        return null;
    }
}
}

类节点:

public class Node<T> {

private T data;
private Node<T> next;

public Node(T data)
{
    this.data = data;
    this.next = null;
}

public Node(T data, Node<T> next)
{
    this.data = data;
    this.next = next;
}

public void setNode(Node<T> next)
{
    this.next = next;
}

public Node<T> getNext()
{
    return this.next;
}

public T getObj()
{
    return data;
}

  }

class Country: 有覆盖方法等于

public class Country  {

private String countryNames;
private SubscriptionYear[] subscriptions;
private int size;
private int location;

public Country(String country)
{
    this.countryNames = country;
}
public Country(String country, int arraylength)
{
    this.countryNames = country;
    this.size = arraylength;
    subscriptions = new SubscriptionYear[size];
    location = 0;
}
//adds the subscription.
public void addSubscriptionYear(int year, double subscription)
{
        subscriptions[location]= new SubscriptionYear(year, subscription);
        ++location;
}

//overrides the toString method and prints out the countries.
public String toString()
{
    System.out.print(countryNames+"\t");
    for(SubscriptionYear s: subscriptions)
    {
        //System.out.print(countryNames+"\t");
        System.out.print(s.getSubscription()+"\t");
    }
    System.out.println();
    return  "";
}
//returns countryName
 public String getName()
 {
    return this.countryNames;
 }
//overrides the equals method and returns country name if found
public boolean equals(Country obj)
{
    System.out.println("In the equals method");
    return this.countryNames.equalsIgnoreCase(obj.countryNames);
}

}

main中的方法调用该函数来比较节点中的国家/地区名称。

private void testRandomListOfCountries(Country [] allCountries)
{   
    Scanner keyboard = new Scanner(System.in);
    System.out.println("How many countries do you want to add to the list?");
    int requestedSize = Integer.parseInt(keyboard.nextLine());


    // Build the list out of a random selection of countries.
    Random random = new Random();
    LinkedList<Country> selectedCountries = new LinkedList<Country>();
    for (int i = 0; i < requestedSize; i++)
    {
        int selectedIndex = random.nextInt(allCountries.length);
        selectedCountries.add(allCountries[selectedIndex]);
    }


    // Note: To debug your list, comment this line in
    System.out.println("List of countries: " + selectedCountries);


    // Check if the name of a country is in the list.
    // If the country is found, print the details.
    // Otherwise output not found.
    System.out.println("\nWhat country do you want to search for?");
    String countryToFind = keyboard.nextLine();
    //Country obj = new Country(countryToFind);
    Country foundCountry = selectedCountries.contains(new Country(countryToFind));
    if (foundCountry != null)
    {
        System.out.println("Country " + countryToFind + " found with details:\n" + foundCountry);
    }
    else
        System.out.println("Country " + countryToFind + " not found.");

}

下面的输出代码:Belize 打印在屏幕上,我输入 Belize 并 即使伯利兹在列表中,它也说找不到

How many countries do you want to add to the list?
4
 European Union 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.010455902 0.014641232 0.022017047 0.033736759 0.059970029 0.099394983 0.172494402 0.290883796 0.468609861 0.647271896 0.88803523  1.180245548 1.773778201 2.896911981 4.555055819 7.189007007 11.51481484 19.70441779 33.91179565 53.57287113 64.80565912 70.93170081 77.89306636 85.94063784 95.79155903 105.012288  115.1562612 120.8409684 121.1416294 119.2250553 121.9304985 123.7159497 
 Sint Maarten (Dutch part)  0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 
 Belize 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.201592581 0.411172831 0.747480214 1.028369629 1.164387324 1.570531759 2.842663676 7.046515722 15.96872731 20.54645981 23.38066005 28.29761545 35.30450132 42.2961808  41.34020042 54.51721037 53.74564807 62.93070205 70.31965347 53.20712214 
 Uganda 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.008423042 0.018684872 0.022640286 0.131691862 0.239741703 0.522799789 1.130100554 1.516028656 2.892006194 4.195756068 4.578959089 6.761102482 13.65261655 26.92003559 28.55294653 37.74438345 47.50472743 45.00206351 
 List of countries: 
 What country do you want to search for?
 Belize
 Country Belize not found.

【问题讨论】:

    标签: java generics singly-linked-list


    【解决方案1】:

    当您覆盖equals 时,它必须是equals(Object),而不是equals(YourClassName)。您实际上并没有覆盖该方法;你创建了一个单独的同名方法,LinkedList 不会调用它。

    【讨论】:

    • 是的。我用来避免此错误的一种做法是,当我打算重写基类方法时,我使用:@Overrides 来记录意图,并让编译器在我犯这样的错误时将我打得头晕目眩.
    • @user2357112 非常感谢。为什么是那个错误?如果你能解释一下,还是有点困惑。 java泛型还是新手
    • @BrianT。为什么是那个错误?仍然有点困惑,我是泛型的新手。还有你如何使用“@overrides”来帮助提醒
    • @LALA...回复比“评论”允许的更完整的答案。
    【解决方案2】:

    回复新的回复,以便我可以引用代码。

    返回@LALA。这个特殊的问题不是泛型,而是如何覆盖关键方法,equals(Object) 定义在 java.lang.Object 中。要覆盖基类中的方法,您必须获得签名点。容易搞砸,某处(java 1.4??)java添加了方法注释@Override。这告诉编译器(以及任何阅读代码的人......包括明天的你)“这个方法旨在覆盖基类(或接口)中的方法;如果不是,请抛出编译时错误,因为我吃饱了。

    按照本指南,您将输入:

    //overrides the equals method and returns country name if found
    @Overrides
    public boolean equals(Country obj)
    ...
    

    编译器会跳进去把你保存在这里,注意它不会覆盖任何东西。正确的是:

    //overrides the equals method and returns country name if found
    @Overrides
    public boolean equals(Object obj)
    ...
    

    我想补充一下……你犯了一个ma​​jor-java-developer-sin。你[试图]写equals(),但你还没有覆盖hashCode()(再次指定@Override在这里更加重要(我个人经常忘记大写'C')。说真的,永远不要编写这两种方法之一。

    作为此答案的作业,请仔细阅读以下内容:

    https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

    https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

    【讨论】:

      猜你喜欢
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多