I have an assignment for school to make a program which results in either true or false. It's about wether a year is a leap year or not. The problem I have at the moment is that i'm using a public static boolean instead of a public boolean.
This is my code:
public class Assignment {
static boolean isLeapYear;
public static void main(String[] args)
{
int year = 2000;
isLeapYear(year);
}
public static boolean isLeapYear(int year) {
if (((year/100)%4 == 0 && year%4 ==0) || (year % 400 == 0))
isLeapYear = true;
else
isLeapYear = false;
System.out.println(isLeapYear);
return isLeapYear;
}
}
The int year is 2000 at the moment but the rules are like this:
A leap year is a year wich can be divided by 4 unless the year is the beginning of a new century (1700, 1800, 1900.....). So even though you can divide 1900 by 4 you can't divide it by 400 so it's false.
So again the question: What do I need to do so i'm able to use a public boolean instead of a public static boolean?
You would need to create an instance of your class to invoke that method from your main method, if you want to make your method non-static. And then you can make your isLeapYear variable non-static: -
boolean isLeapYear;
public static void main(String[] args)
{
int year = 2000;
new Assigment().isLeapYear(year);
}
public boolean isLeapYear(int year) {
// access isLeapYear as `this.isLeapYear` or just `isLeapYear`
}
But, precisely, you don't need to store your result in a boolean variable. If you want to return a boolean value of some expression, then you can just return that expression.
So, just having this code in your method would also work fine, and it is more readable, and let that method be static: -
return (((year/100)%4 == 0 && year%4 ==0) || (year % 400 == 0))
And from your main call: -
System.out.println("Year : " + year + ", is leap year: " + isLeapYear(year));
You don't need to store this result anywhere.
Use:
public static boolean isLeapYear(int year)
{
return (((year/100)%4 == 0 && year%4 ==0) || (year % 400 == 0));
}
Static methods can only access static variables, only instance methods can access instance methods, which you can infer if you think Object oriented.
Just in case you should store the Boolean isLeapYear
public class Testing {
boolean isLeapYear;
public static void main(String[] args)
{
int year = 2000;
new Testing().isLeapYear(year);
}
public boolean isLeapYear(int year) {
if (((year/100)%4 == 0 && year%4 ==0) || (year % 400 == 0))
isLeapYear = true;
else
isLeapYear = false;
System.out.println(isLeapYear);
return isLeapYear;
}
}
Does your assignment say it has to be stored in a class or instance variable? If not, there is no need for public boolean isLeapYear or public static boolean isLeapYear, just return the result of the calculation and store it in a local variable like this:
public static boolean isLeapYear(int year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
in main method:
int year = 2000;
boolean isLeap = isLeapYear(year);
System.out.println(isLeap);
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I wrote code to check whether the year entered is a leap year
or not. But now I am trying to add on so that If it is not, then my program must display the number of years until the next leap year. This is how I did The code for the first bit of my program
Turn this into a function that returns true/false based on a parameter. Then do the initial check, and after that a simple for loop from year to year + 4, and call the function with these new values.
public static void main(String args[]) {
int year = 2021;
System.out.println(IsLeapYear(year));
for (int i = year; i < year + 4; i++) {
if (IsLeapYear(i)) {
System.out.println("The next leap year is " + i);
break;
}
}
}
public static boolean IsLeapYear(int year) {
return ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));
}
Output:
false
The next leap year is 2024*/
As per #mcemperor's request, here is a version with a while loop, which works correctly:
public static void main(String args[]) {
int year = 2020;
int i = year;
System.out.println(IsLeapYear(year));
while (!IsLeapYear(++i));
System.out.println("The next leap year is " + i);
}
public static boolean IsLeapYear(int year) {
return ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));
}
You can find the closest leap yea by using an iterator (generator) to compute each successive leap year:
import java.time.LocalDateTime;
public class LeapYearDemo {
public static void main(String [] args) {
System.out.println(closestLeapYear(LocalDateTime.now()));
}
public static int closestLeapYear(LocalDateTime date) {
return LeapYearIterator.isLeapYear(date.getYear())
? date.getYear()
: new LeapYearIterator(date.getYear()).next();
}
}
import java.util.GregorianCalendar;
import java.util.Iterator;
public class LeapYearIterator implements Iterator<Integer>, Iterable<Integer> {
private static final GregorianCalendar CALENDAR;
private int year;
static {
CALENDAR = (GregorianCalendar) GregorianCalendar.getInstance();
}
public LeapYearIterator(int yearStart) {
this.year = yearStart;
}
#Override
public Integer next() {
do this.year++;
while (!isLeapYear(this.year));
return this.year;
}
#Override
public boolean hasNext() { return true; }
#Override
public Iterator<Integer> iterator() { return this; }
public static boolean isLeapYear(int year) {
return CALENDAR.isLeapYear(year);
}
}
I based this on some JavaScript code I wrote below.
const isLeapYear = (year) =>
year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
function* nextLeap(date) {
let year = date.getFullYear() + 1;
while (true) {
if (isLeapYear(year++)) {
yield (year - 1);
}
};
};
const closestLeapYear = (date) =>
isLeapYear(date.getFullYear())
? date.getFullYear()
: nextLeap(date).next().value;
console.log(closestLeapYear(new Date()));
I'm trying to create a simple date class. My professor also wants us to include our own .equals method in the date class which should compare two objects. My problem is my method returns false unless I compare the exact same object, even if their values are the same.
Here is my driver:
public class Lab3Driver {
public static void main(String[] args) {
Date theDate = new Date(6, 30, 1995);
Date anotherDate = new Date(6, 30, 1995);
System.out.println(theDate.equals(anotherDate));
System.out.println(theDate);
System.out.println(anotherDate);
}
}
Here is my date class:
public class Date {
private int month;
private int day;
private int year;
public Date() // default no arg constructor
{
this.month = 1; // set to date I completed this class, for fun.
this.day = 26;
this.year = 2019;
}
public Date(int m, int d, int y) // normal constructor in case you want to initialize variables upon object declaration
{
this.month = m;
this.day = d;
this.year = y;
}
public int getMonth() {
return month;
}
public void setMonth(int month)
{
if (month >= 1 && month <= 12) // if else that checks and makes sure months are between 1 and 12
{
this.month = month;
}
else
{
System.out.println("Invalid month input. Months are between 1 and 12.");
}
}
public int getDay()
{
return day;
}
public void setDay(int day)
{
if (day >= 1 && day <= 31) // if else that checks and makes sure days are between 1 and 31
{
this.day = day;
}
else
{
System.out.println("Invalid day input. Days are between 1 and 31.");
}
}
public int getYear()
{
return year;
}
public void setYear(int year) // year can be set to anything, in the case that this program is used for something
{ // other than the present day, as in a reference to the past or future
this.year = year;
}
public String toString() // to string in order to print out the date that is stored
{
String theDate = "The date is: " + this.month + "/" + this.day + "/" + this.year;
return theDate;
}
public boolean equals(Object that) // compares two objects and checks for null/type casting
{
if (this == that)
return true;
else if(that == null || that.getClass()!= this.getClass())
{
System.out.println("Null or type casting of argument.");
return false;
}
else
return false;
}
Something with this method is creating a problem I think:
public boolean equals(Object that) // compares two objects and checks for null/type casting
{
if (this == that)
return true;
else if(that == null || that.getClass()!= this.getClass())
{
System.out.println("Null or type casting of argument.");
return false;
}
else
return false;
}
It's normal, because you wrote
else {
return false;
}
So whenever that object has a different reference and is from the same class you go in the else statement above which returns false.
You should implement the code instead of returning false, for example:
public boolean equals(Object that) // compares two objects and checks for null/type casting
{
if (this == that)
return true;
else if(that == null || that.getClass()!= this.getClass())
{
System.out.println("Null or type casting of argument.");
return false;
}
else
return this.year == that.getYear() && ...;
}
if (this == that)
This line does not compare the objects. This only verifies if your object is in the same memory space, basically asking if it is exactly the same object (pointing to the same place).
If you want to compare two different objects, two different instances like
Date theDate = new Date(6, 30, 1995);
Date anotherDate = new Date(6, 30, 1995);
then you'll have to add more lines of code that check each value in each variable in each of the objects, or override the ' == ' method to make it compare the values.
Sοme οther things tο nοte:
As Nate has already said, yοu have tο cοmpare the individual fields οf the twο οbjects yοu are cοmparing. Tο dο that, yοu can use return year == that.getYear() && day == that.getDay() && mοnth == that.getMοnth().
But wait! Yοur equals methοd takes in an Object. Therefοre, we can't use thοse methοds. There are twο ways yοu can fix this.
Dο an instanceοf check at the beginning οf the methοd, and then cast the parameter tο a Date οbject.
Restrict the parameter οf yοur methοd tο οnly allοw Date οbjects.
Persοnally, I wοuld dο the latter, since an errοr will pοp up at cοmpile time if yοu used a nοn-Date οbject. Hοwever, if yοu did a type check in methοd and thrοw an exceptiοn if the type check failed, yοu may never nοtice an errοr if yοu prοvided an argument that is nοt a Date οbject until the method is called.
One thing you need to make sure that if you override the equals method you should also override the hashCode method.
For your reference, please read the section
https://www.baeldung.com/java-equals-hashcode-contracts#hashcode
I have completed both the overridden methods for you.
#Override
public boolean equals(Object that) {
if (this == that)
return true;
if(!(that instanceof Date))
return false;
if(that == null || that.getClass()!= this.getClass())
return false;
Date anotherDate = (Date) that;
if(this.month == anotherDate.month
&& this.day == anotherDate.day
&& this.year == anotherDate.year)
return true;
return false;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (month ^ (month >>> 16));
result = prime * result + (int) (day ^ (day >>> 16));
result = prime * result + (int) (year ^ (year >>> 16));
return result;
}
I have 1 constructor and 1 factory method for my Date class. The first one just have 3 int parameter represent month, day and year. And the second one, I provide it in case user give string as one parameter to represent month/day/year.
As you can see in the main(), I forget to call parseIt, the factory method. But compiler still provide correct result. So question is: can JAVA call this factory method implicitly?
Please take a look the 1st constructor and 2nd factory methods:
import java.io.*;
class Date {
private int month;
private int day;
private int year;
public Date(int month, int day, int year) {
if (isValidDate(month, day, year)) {
this.month = month;
this.day = day;
this.year = year;
} else {
System.out.println("Fatal error: Invalid data.");
System.exit(0);
}
}
public static Date parseIt(String s) {
String[] strSplit = s.split("/");
int m = Integer.parseInt(strSplit[0]);
int d = Integer.parseInt(strSplit[1]);
int y = Integer.parseInt(strSplit[2]);
return new Date(m, d, y);
}
public static boolean isLeapYear(int year) {
if (year%4 != 0) {
return false;
} else if (year%100 == 0 && year%400 != 0) {
return false;
}
return true;
}
public static int daysInMonth(int month, int year) {
if (month == 2) {
if (isLeapYear(year)) {
return 29;
} else {
return 28;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
} else {
return 31;
}
}
public static boolean isValidDate(int month, int day, int year) {
if (year < 1 || year > 9999 || month <= 0 || month > 12 || day <= 0) {
return false;
} else if (day > daysInMonth(month, year)) {
return false;
}
return true;
}
public static void main(String[] argv) {
Date d1 = new Date(1, 1, 1);
System.out.println("Date should be 1/1/1: " + d1);
d1 = new Date("2/4/2");
System.out.println("Date should be 2/4/2: " + d1);
}
}
No, it will not. There is no constructor which takes in a string, so it would throw a syntax error. In order to make it work, you would have to define a constructor which takes in a String parameter performs the same logic as the parseIt(String) function.
This is the code I'm using to figure out if a year is a leap year or not:
public class leap_year {
public static void main(String args[])
{
isLeapYear(2009)
}
public static boolean isLeapYear(int year) {
if (year % 4 != 0) {
return false;
} else if (year % 400 == 0) {
return true;
} else if (year % 100 == 0) {
return false;
} else {
return true;
}
}
}
But when I run the code nothings shows up. What am I doing wrong?
Nothing prints out, because you haven't ordered it! Use System.out.println(...) to print the output out to the console.
Your code should look like this:
boolean bool = isLeapYear(2009);
System.out.println(bool);
Or print it out directly without using any variable:
System.out.println(isLeapYear(2009));
Your code is working perfectly, you just need to print the result of the method somewhere...
use System.out.println and your method as parameter....
System.out.println(isLeapYear(2009));
System.out.println(isLeapYear(2016));
I've been debugging for hours, and I finally found where the problem is. NOW I have to fix it :)
I thinks something strange happens.
I'm creating an date app, where I calculate which day it is (with leapyear corrections etc).
I have a method, where I take a Year object.
private int totalDays(Year yearnumber) {
System.out.println("Boolean check 1: " + yearnumber.getLeapYear());
//calculate days for whole year//
int daysWholeYear = 0;
for (int i = year.getYearZero(); i < yearnumber.getYear(); i++) {
// here i will add all the days (366) from the leapyears //
if (yearnumber.isLeapYear(i) == true) {
totalDays += year.getLengthyear() + 1;
System.out.println("Boolean check 2: " + yearnumber.getLeapYear());
} else {
totalDays += year.getLengthyear();
}
}
System.out.println("Boolean check 3: " + yearnumber.getLeapYear());
My first two boolean checks are ok.
Code (without the boolean check looped in the for loop)
Boolean check 1: true
Boolean check 2: true
Boolean check 3: false
I need my Boolean in the next lines of my method, where I calculate the days of the months (non whole years). However, my program now thinks that the year is not a leap year and therefore makes wrong calculations.
Because this Boolean changes in my program, the rest of my calculation are off. Can someone explain my why this happens? :)
EDIT: code from my year class:
public class Year {
private static int yearzero = 1753;
private static int lengthYear = 365;
private int year;
private boolean leapYear;
private int startYear; //are used for an interval calculations
private int eindYear; //
public Year(int year) {
this.year = year;
this.leapYear = isLeapYear(year);
}
boolean isLeapYear(int year) {
return leapYear = (year % 400 == 0) ||
((year % 100) != 0 && (year % 4 == 0));
}
public int getYear(){
return year;
}
public int getYearzero () {
return yearZero;
}
public int getLengthYear() {
return lengthYear;
}
public boolean getLeapYear() {
return leapYear;
}
}
Your isLeapYear function sets the object's leapYear variable. This is because the yearnumber.isLeapYear(i) == true will fail, and yearnumber.leapYear will be set to false.
Change
boolean isLeapYear(int year) {
return leapYear = (year % 400 == 0) ||
((year % 100) != 0 && (year % 4 == 0));
}
to:
boolean isLeapYear(int year) {
return ((year % 400 == 0) ||
((year % 100) != 0 && (year % 4 == 0)));
}