Home > database >  Take a value from a list through a getter method?
Take a value from a list through a getter method?

Time:06-02

I have 3 classes, Human, Date, and Zodiac. In Date I have two int types, month and day. I have normal constructor and getter. In Human I have a String name and a birthday from the type Date.

My Class Date:

public class Date {
    private int month;
    private int day;
    
    public Date(int month, int day) {
        this.month = month;
        this.day = day;
    }
    public int getMonth() { return month;}

    public int getDay() {return day;}

My Class Human

public class Human {
    private String name;
    private Date birthday;

    public Human(String name, Date birthday) {
        this.name = name;
        this.birthday = birthday;
    }

   public String getName() { return name;}
   
   public BirthDate getBirthday() { return birthday;}

In My class Zodiac I have a Main where I created some objects. Then I have a method zodiacToHuman were I give a Human his star sign. But this method didn't work at all. The method has a List as Parameter and returns a Map.

My method in class Zodiac:

public static Map<Human, String> zodiacToHuman(List<Human> humanlist){
     Map<Human, String> personSign = new HashMap<>();
     Human human;
     String sign = "";
     int day = Date.getDay();
     int month = Date.getMonth();
     if (month == 1) {
            if (day < 20)
                sign = "capricornus";
                humanSign.put(human, sign);
            else
                sign = "aquarius";
                humanSign.put(human, sign);
     }//and so on
}

This is the error I get:

Non-static method 'getDay()' cannot be referenced from a static context

Non-static method 'getMonth()' cannot be referenced from a static context

Variable Human might not have been initialized

Can someone help me?

CodePudding user response:

You can't do int day = Date.getDay()

Create an object first of the Date class and use it to get the day and month

Data date = new Date()
int day = date.getDay()
int month = date.getMonth()

Also you haven't initialised your Human class object. You can write

Human human = new Human(some_day, some_month)

CodePudding user response:

As I understand the humanList contains entries of Human Objects. You should try itterating the list, like so

public static Map<Human, String> zodiacToHuman(List<Human> humanlist){
     Map<Human, String> personSign = new HashMap<>();
     for (Human human : humanList){
       String sign = "";
       int day = human.getBirthday().getDay();
       int month = human.getBirthday().getMonth();
       if (month == 1) {
            if (day < 20){
                sign = "capricornus";
            }else{
                sign = "aquarius";
            }
       }//and so on
       humanSign.put(human, sign);
    }
}

CodePudding user response:

Let's change the name of Date to more precise MonthWithDay.

We can shorten the code of that class by making it a record. By default, the implicitly created getter methods are named the same as the member field name.

public record MonthWithDay( int month , int day ) { }

Similarly we can define your Human class as a record in one short line.

public record Human( String name , MonthWithDay monthDayWhenBorn ) { }

Regarding your method to determine zodiac:

public static Map<Human, String> zodiacToHuman(List<Human> humanlist){ …

… there is no need for static. In your scenario, that seems like a reasonable feature on your Human class.

Tip: In object-oriented programming, using static is not object-oriented. Try to minimize use of static. Use as a last resort only.

public record Human( String name , MonthWithDay monthDayWhenBorn )
{
    public String zodiac ( )
    {
        int day = this.monthDayWhenBorn.day();
        int month = this.monthDayWhenBorn.month();
        if ( month == 1 )
        {
            if ( day < 20 )
            { return "capricornus"; }
            else
            { return "aquarius"; }
        }
        return "other";
    }
}

Populate some example data.

List < Human > humans =
        List.of(
                new Human( "Alice" , new MonthWithDay( 1 , 11 ) ) ,
                new Human( "Alice" , new MonthWithDay( 1 , 22 ) ) ,
                new Human( "Carol" , new MonthWithDay( 11 , 27 ) )
        );

Create your map of human to zodiac.

Map< Human , String > mapOfHumanToZodiac = new HashMap<>() ;

Loop through each Human object, interrogate for its zodiac, and place into our map.

for ( Human human : humans )
{
    mapOfHumanToZodiac.put( human , human.zodiac() );
}

Dump to console.

System.out.println( "mapOfHumanToZodiac = "   mapOfHumanToZodiac );

mapOfHumanToZodiac = {Human[name=Alice, monthDayWhenBorn=MonthWithDay[month=1, day=11]]=capricornus, Human[name=Alice, monthDayWhenBorn=MonthWithDay[month=1, day=22]]=aquarius, Human[name=Carol, monthDayWhenBorn=MonthWithDay[month=11, day=27]]=other}

By the way, in real work we would define an enum to represent each of the zodiac signs rather than use mere strings. Doing so provides type-safety, ensures valid values (avoids errors from typos in the strings), and makes the code more self-documenting.

java.time

Java comes with an industry-leading framework of date-time classes, found in the java.time package. These classes include a MonthDay class. So no need to invent your own. We can delete your MonthWithDay class.

Tweak the Human class.

public record Human( String name , MonthDay monthDayWhenBorn )  // <-- Use java.time.MonthDay class.
{
    public String zodiac ( )
    {
        int day = this.monthDayWhenBorn.getDayOfMonth();        // <-- Use java.time.MonthDay class.
        int month = this.monthDayWhenBorn.getMonthValue();      // <-- Use java.time.MonthDay class.
        if ( month == 1 )
        {
            if ( day < 20 )
            { return "capricornus"; }
            else
            { return "aquarius"; }
        }
        return "other";
    }
}

Change how we create the sample data.

List < Human > humans =
        List.of(
                new Human( "Alice" , MonthDay.of( 1 , 11 ) ) ,  // <-- Use java.time.MonthDay class.
                new Human( "Alice" , MonthDay.of( 1 , 22 ) ) ,
                new Human( "Carol" , MonthDay.of( 11 , 27 ) )
        );

And we get the same results.

CodePudding user response:

Errors and reasons

Variable Human might not have been initialized

Its not a error its a warning that saying human variable might be null as you have only decalre the variable human. To initialize either you need to create an instance or assign null to it

Human human = new Human(YOUR VALUES);
//or 
Human human = null;

Non-static method 'getDay()' cannot be referenced from a static context

Non-static method 'getMonth()' cannot be referenced from a static context

You cannot access public methods of a class directly without creating an object.

NOTE

As per my understanding you are giving each human a sign value.You can achive the same while you are creating each human object and later on create a map from it. Eg:

public class Human {
    private String name;
    private Date birthday;
    private String sign;

    public Human(String name, Date birthday) {
        this.name = name;
        this.birthday = birthday;
        assignZodiac();
    }   

    private void assignZodiac(){
        String sign = "";

        //getting birhday month and day values
        int day = birthday.getDay();
        int month = birthday.getMonth(); 

    // your logic of assignment
        if (month == 1) {
                    if (day < 20)
                        sign = "capricornus";
                    else
                        sign = "aquarius";
            }//and so on

    }

//getter setter

}

Now you can create a map from the list. eg:

    // human list has been already created
    Map<Human,String> humanSign=newHasmap<>();    
    for(Human human : humanList) {
        humanSign.put(human,human.getSign()) //asuming getSign is the getter for sign filed in Human.
    }

Also I would suggest you to change Date class name to something else since java already has a class of the same name. It's just for naming convection

  • Related