Trouble determining the range of years in a linked list

83 Views Asked by At

Hello guys i am having trouble implementing this particular problem. Every time i add a subscription to the list check if i need to update the "minYear" and "maxYear". Later use "minYear" and "maxYear" to check if the requested subscription period is valid. Basically I'm trying to determine the range of years of the linked list of subscriptions.

Class SubscriptionYear: First reads the year and cellular data of a particular country. This read from a file. It takes in the year and stats data for that year.

Below is my code for SubscriptionYear:

public class SubscriptionYear {

private int year;
private double subscriptions;
SubscriptionYear next;

//stores the year and it's statistical data.
public SubscriptionYear(int year,double subscriptions)
{
    setYear(year);
    setSubscription(subscriptions);
    this.next = null;
}
//sets the year
public void setYear(int Year)
{
    this.year= Year;
}
//sets the cellular data.
public void setSubscription(double value)
{
    this.subscriptions = value;
}
public int getYear()
{
    return year;
}   
 //returns the stat data
public double getSubscription()
{
    return subscriptions;
}
public String toString()
{
    return "Number of Subscriptions: "+subscriptions;
}
//sets the node
public void setNode(SubscriptionYear next)
{
    this.next = next;
}
public SubscriptionYear getNext()
{
    return this.next;
}
}

class Country: This reads the Country Name and acts as a container for the Object node SubscripitpnYear that stores the year and stats data. It has variable field minYear and maxYear to check when a subscription is added to the list if it needs to be updated. use the minYear and maxYear to check if a subscription requested is valid. This is where i am having trouble implementing when i add a SusbcriptionYear to the list how do i check if i need to update minYear and maxYear? And use minYear and maxYear to check if a subscription is valid?

my class country:

public class Country  {

//variable fields.
private String countryNames;
private SubscriptionYear subscriptions;
private int minYear;
private int maxYear;

public Country(String country)
{
    this.countryNames = country;
    this.subscriptions = null;
    this.maxYear = 0;
    this.minYear = 9999;

}
//adds the subscription.
public void addSubscriptionYear(int year, double subscription)
{
    SubscriptionYear newNode = new SubscriptionYear(year, subscription);
    if(this.isEmpty())
    {
        newNode.setNode(subscriptions);
        subscriptions = newNode;
    }
    else{
        SubscriptionYear current = subscriptions;
        while(current.getNext()!=null)
        {
            current = current.getNext();
        }
        current.setNode(newNode);
    }
}

//need help implementing this function
public void update(int minYear, int maxYear)
{

}

//overrides the toString method and prints out the countries.
public String toString()
{
    String result="";
    result += "\n"+this.countryNames;
    SubscriptionYear current = subscriptions;
    while(current!=null)
    {
        result+="\t"+current.getSubscription();
        current = current.getNext();        
    }
    return result;
}
//returns countryName
 public String getName()
{
    return this.countryNames;
}
//overrides the equals method and returns country name if found
public boolean equals(Object obj)
{
    return this.countryNames.equalsIgnoreCase(((Country) obj).getName());
}
public boolean isEmpty()
{
    return (subscriptions == null);
}
1

There are 1 best solutions below

3
On

-1- Humm, lots of code here but I'll try.

your getNext() method confused me, and probably many experienced Java developers. In java collections (e.g. List), you can get an iterator (https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html). There "hasNext()" is a boolean "is there another object?) and can be used in your while() control. next() both returns the next item and advances the iterator to point to the following item. Hence... having getNext() in both your while(), and in the following body looks suspect.

Your code uses setNode() to set "next", and getNext() to retrieve it. Conventionally (and hence easier for many to understand intent) would be to follow naming conventions. For member variable "node" this would be setNode() & getNode().

-2- OK, that said, it looks like this code:

    SubscriptionYear current = subscriptions;
    while(current.getNext()!=null)
    {
        current = current.getNext();
    }
    current.setNode(newNode);

walks the subscriptions and places newNode at the end.

Humm, I'm giving up confused. You are using the same name "subscriptions" as two distinctly different things. In SubscriptionYear it appears to be a count of how many subscriptions you have (why double? int seems better). However, in Country it is your home-made-list of SubscriptionYear, holding the 1st one.

IOM, the route to solution includes clarifying your code, using better names so you can understand what it does.

-3- do you have a specific question beyond the comment in update() ? Maybe you should indicate what that method is supposed to do, propose logic, etc.

-- Other observations:

-1- Country.equals() is sketchy. It should return false, not a ClassCastException if the passed in object is not of the same class. Better:

public boolean equals(Object obj)
{
    if (this==obj){return true;}
    if (! (obj instanceof Country)) { return false; }
    return this.countryNames.equalsIgnoreCase(((Country) obj).getName());
}

-2- You have committed java-developer-sin; implementing ONE of equals() and hashCode(). It is important to -always- implement both, or neither. More on that here (read both equals() and hashCode() descriptions).

https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html