I am trying to get the hour component of an object, which is an int, and increment it by 1. So 5 would be 6. I tried to do clocks[i].getHour() = clocks[i].getHour()+1, but this was not allowed and would say I need a variable on the left.
public void daylightSavingsTime(Clock[] clocks) {
for(int i = 0; i <clocks.length; i++) {
int a = clocks[i].getHour()+1;
}
Probably you'd need to write/use a setter function setHour(int newHour) ,
and then you could do something along the lines of:
public void daylightSavingsTime(Clock[] clocks) {
for(int i = 0; i <clocks.length; i++) {
clocks[i].setHour(clocks[i].getHour()+1);
}
Explanation of your statement.
clocks[i].getHour() = clocks[i].getHour()+1;
//To simplify
Clock clock = clocks[i];
clock.getHour() = clock.getHour()+1; //thing you are trying to do.
Suppose clock hours field is 6. What the compiler will do. When it sees clock.getHours() it knows the value is 6. To compiler your statement looks like
6 = 6+1
Obviously no language wants to change the value of 6 to 7
But int a = clocks[i].getHour()+1; is a valid statement as a will be assigned to 7.
To increment the hour in clock just use just do
clock.hours = clocks[i].getHour()+1;
but now hours property is public and can be easily abused like clock.hours = 100; but we may not want it to be 100, but to increase the date as 100 > 24. So use set method like clock.setHour(a+1) this method will internally handle the hour like
Class Clock{
// like that.. it may be different..
void setHour(int hour){
this.day += hour/24;
this.hour += hour%24;
}
}
Related
I'm trying to display in the Message dialog on the JOptionPane the highest number of sales from my array of sales.
And I also want to show in which month they happened, but I am failing to find a way to display the month.
public static void main(String[] args) {
int[] CarSales= {1234,2343,1456,4567,8768,2346,9876,4987,7592,9658,7851,2538};
String [] Months = {"January","February","March","April","May","June"
,"July ","August","September","October","November","December" };
int HighNum = CarSales[0];
for(int i = 0; i < CarSales.length; i++)
{
if(CarSales[i] > HighNum)
{
HighNum = CarSales[i];
}
}
JOptionPane.showMessageDialog(null,"The highest car sales value is :"+HighNum +
"-which happened in the month of");
}
Use the Power of Objects
Avoid using parallel arrays in Java. It brings unnecessary complexity, makes the code brittle and less maintainable.
Your code doesn't automatically become object-oriented just because of the fact that you're using an object-oriented language.
Objects provide you an easy way of structuring your data and organizing the code (if you need to implement some functionality related, to a particular data you know where it should go - its plane is in the class representing the data).
So, to begin with, I advise you to implement a class, let's call it CarSale:
public static class CarSale {
private Month month;
private int amount;
// getters, constructor, etc
}
Or, if you don't need it to be mutable, it can be implemented as a Java 16 record. In a nutshell, record is a specialized form of class, instances of which are meant to be transparent carriers of data (you can not change their properties after instantiation).
One of the greatest things about records is their concise syntax. The line below is an equivalent of the fully fledged class with getters, constructor, equals/hashCode and toString (all these would be generated for you by the compiler):
public record CarSale(Month month, int amount) {}
java.time.Month
You've probably noticed that in the code above, property month is not a String. It's a standard enum Month that resides in java.time package.
When you have a property that might have a limited set of values, enum is always preferred choice because contrary to a plain String, enum guards you from making typo and also enums have an extensive language support. So you don't need this array filled with moth-names.
That's how your code might look like:
CarSale[] carSales = {
new CarSale(Month.JANUARY, 1234),
new CarSale(Month.FEBRUARY, 2343),
new CarSale(Month.MARCH, 1456),
// ...
};
// you might want to check if carSales is not is empty before accessing its first element
CarSale best = carSales[0];
for (CarSale sale: carSales) {
if (sale.getAmount() > best.getAmount()) best = sale;
}
JOptionPane.showMessageDialog(null,
"The highest car sales value is :" + best.getAmount() +
" which happened in the month of " + best.getMonth());
Note
Try to keep your code aligned with Java naming conventions. Only names of classes and interface should start with a capital letter.
In case if you've heard from someone that usage of parallel arrays can improve memory consumption, then I would advise to examine this question dipper and take a look at questions like this Why use parallel arrays in Java? In case of such tiny arrays the only thing are disadvantages of a fragile code.
There are multiple solutions but i'll give you the simplest based on your structure.
Just declare one String variable and assign the value whenever you change the highest num.
public static void main(String[] args) {
int[] CarSales= {1234,2343,1456,4567,8768,2346,9876,4987,7592,9658,7851,2538};
String [] Months = {"January","February","March","April","May","June"
,"July ","August","September","October","November","December" };
int HighNum = CarSales[0];
String month = Months[0];
for(int i = 0; i < CarSales.length; i++)
{
if(CarSales[i] > HighNum)
{
HighNum = CarSales[i];
month = Months[i];
}
}
JOptionPane.showMessageDialog(null,"The highest car sales value is :"+HighNum +
"-which happened in the month of " + month);
}
Keep an index. Whenever you change the highest found, update the index.
public static void main(String[] args) {
int[] CarSales= {1234,2343,1456,4567,8768,2346,
9876,4987,7592,9658,7851,2538};
String [] Months = {"January","February","March","April","May","June"
,"July ","August","September","October","November","December" };
int HighNum = CarSales[0];
int highMonth = 0;
for(int i = 0; i < CarSales.length; i++)
{
if(CarSales[i] > HighNum)
{
HighNum = CarSales[i];
highMonth = i;
}
}
JOptionPane.showMessageDialog
(null,"The highest car sales value is :"+HighNum +
"-which happened in the month of " + Months[highMonth]);
}
Hey I am a high school and I found the solution to my problem but confused on why it's doing what it's doing can someone explain? Also I tried looking for the answer but couldn't find it so sorry if someone's already answered this.
So at getAverage() I state int i; and initialize it in the foreach loop but when it runs it says "variable i might not have been initialized"? I found the solution to this was just make int i = 0; but i'm confused because I know you can state a variable and not initialize it at that time as long as you initialize it later. So what makes this so special?
public class ArrayAverage
{
private int[] values;
public ArrayAverage(int[] theValues)
{
values = theValues;
}
public double getAverage()
{
// Problem here
int i; // Solution: int i = 0;
for(int value : values){
i += value;
}
double avg = (double)i / values.length;
return avg;
}
}
// This pseudo code code has nothing to do with above code
// but is example of what I know can be done but isn't
int i;
i = 10;
System.out.println(i);
//Output would be 10
The issue is that the you're adding the variable i to itself, and another value. However, the initial value for i has not been defined in the previous code. This is the reason that i = 0 would make the code work, as the program now understands that for the first loop, it has to add the value to 0, then the second loop will know to add the previous value, to the new value.
Hope this helped.
I'm currently developing some functionality that needs to either subtract or add time to a Calendar class instance. The time I need to add/sub is in a properties file and could be any of these formats:
30,sec
90,sec
1.5,min
2,day
2.333,day
Let's assume addition for simplicity. I would read those values in a String array:
String[] propertyValues = "30,sec".split(",");
I would read the second value in that comma-separated pair, and map that to the relevant int in the Calendar class (so for example, "sec" becomes Calendar.SECOND, "min" becomes Calendar.MINUTE):
int calendarMajorModifier = mapToCalendarClassIntValues(propertyValues[1]);
To then do the actual operation I would do it as simple as:
cal.add(calendarMajorModifier, Integer.parseInt(propertyValues[0]));
This works and it's not overly complicated. The issue is now floating values (so 2.333,day for eaxmple) - how would you deal with it?
String[] propertyValues = "2.333,day".split(",");
As you can imagine the code becomes quite hairy (I haven't actually written it yet, so please ignore syntax mistakes)
float timeComponent = Float.parseFloat(propertyValues[0]);
if (calendarMajorModifier == Calendar.DATE) {
int dayValue = Integer.parseFloat(timeComponent);
cal.add(calendarMajorModifier, dayValue);
timeComponent = (timeComponent - dayValue) * 24; //Need to convert a fraction of a day to hours
if (timeComponent != 0) {
calendarMajorModifier = Calendar.HOUR;
}
}
if (calendarMajorModifier == Calendar.HOUR) {
int hourValue = Integer.parseFloat(timeComponent);
cal.add(calendarMajorModifier, hourValue);
timeComponent = (timeComponent - hourValue) * 60; //Need to convert a fraction of an hour to minutes
if (timeComponent != 0) {
calendarMajorModifier = Calendar.MINUTE;
}
}
... etc
Granted, I can see how there may be a refactoring opportunity, but still seems like a very brute-forceish solution.
I am using the Calendar class to do the operations on but could technically be any class. As long as I can convert between them (i.e. by getting the long value and using that), as the function needs to return a Calendar class. Ideally the class also has to be Java native to avoid third party licensing issues :).
Side note: I suggested changing the format to something like yy:MM:ww:dd:hh:mm:ss to avoid floating values but that didn't pan out. I also suggested something like 2,day,5,hour, but again, ideally needs to be format above.
I'd transform the value into the smallest unit and add that:
float timeComponent = Float.parseFloat(propertyValues[0]);
int unitFactor = mapUnitToFactor(propertyValues[1]);
cal.add(Calendar.SECOND, (int)(timeComponent * unitFactor));
and mapUnitToFactor would be something like:
int mapUnitToFactor(String unit)
{
if ("sec".equals(unit))
return 1;
if ("min".equals(unit))
return 60;
if ("hour".equals(unit))
return 3600;
if ("day".equals(unit))
return 24*3600;
throw new InvalidParameterException("Unknown unit: " + unit);
}
So for example 2.333 days would be turned into 201571 seconds.
I'm having some trouble figuring this out. I have a while statement with an expression that should be evaluated on each loop. I feel like I am thinking about this wrong.
What I'm trying to do is loop through the expression experience >= experienceCap until it is false. The experienceCap is set correctly on each loop, but the while expression values never change even though the values actually do change on each loop.
public void refreshExperience() {
int experience = getExperience(); //10
int experienceCap = getExperienceCap(); //100
while (experience >= experienceCap) {
newExperienceCap();
refreshExperience();
}
}
This results in some log output like:
experience: 10
experienceCap: 100
experience: 10
experienceCap: 450
experience: 10
experienceCap: 1120
experience: 10
experienceCap: 2337
And an inevitable crash.
I would very much appreciate any input, thank you!
The loop values are not being updated, so it is confusing that in your output it shows experienceCap increases. Without seeing all the code i can only guess that the values you are logging are not the ones declared in refreshExperiece.
public class Test {
int experience = 10;
int experienceCap = 100;
public void refreshExperience() {
while (experience <= experienceCap) {
experience = getExperience();
experienceCap = getExperienceCap();
}
}
The above code shows experience and experienceCap being initialized to 10 and 100 respectively. Inside the loop these values are updated with the returned value from getExperience and getExperienceCap respectively. How you are updating experience and experienceCap is up to you but this is a simple example:
private int getExperience() {
return experience + 5;
}
private int getExperienceCap() {
return experienceCap - 10;
}
This is a typical value vs reference problem.
You seem to expect that int experience is a reference, but it is not.
I have
public int compareTo(Object other)
{
}
I need to be able to compare two different sets of numbers and the numbers in the corresponding places.
For example:
Time t1 = new Time(17, 12);
System.out.println(t1);
Time t2 = new Time(9, 45);
System.out.println(t2);
System.out.println("Greater Than:");
System.out.println(t1.compareTo(t2));
And the output would be
1712
0945
Greater Than:
1
In the time class, the first number is hours while the second number is the minutes. I need help comparing the two numbers.
My time class uses
public Time (int y, int x)
{
minute = x;
hour = y;
if (minute>59 || minute<0)
{
minute = 0;
}
if (hour>=24 || hour<0)
{
hour=0;
}
}
How would i compare two new time objects to each other?
First implement the Comparable interface with the correct generic type, in your case Comparable<Time>.
Then you're able to access the other object's attributes.
Your method will now look like this:
public int compareTo(Time otherTime)
{
//... compare things here... like:
return hour.compareTo(otherTime.getHour());
}
This is a sample, you have to implement compare logic yourself, since I don't know if this is an assignment.
The logic has nothing technical. Tell us verbally how you are doing the comparison in your mind when you faced 17:12 & 09:45. If you can speak out in a systematic way, then there should be no problem writing it as code.
I can understand you maybe a total newbie in programming that you have even no clue in writing a most simple line of code. However in programming world, no one is gonna lead you by grabbing your hand to write. You should try to solve it by yourself.
I won't give you a direct answer. However, this is a little example of similar problem. Assume there is a grading system like this, where A1 < A2 < A3 ... < An < B1 < B2 < B3... < C1....
What I am going to do the comparison is, first I will compare the alphabet part, if grade1's alphabet is larger/smaller than grade2's alphabet, I won't need to care about the number part, and I can return -1/1 according to the alphabet being smaller/larger. If the alphabet is the same, then I need to compare the number part, and return 1,-1 and 0 depending on the result.
Then the code will look like something like (half-psuedo code)
public class Grade implements Comparable {
char level; // A,B,C,D
int sublevel; // 1,2,3,4
// ctor, getters/setters etc
#Override
public int compareTo(Grade other) {
// compare the alphabet part
if (this.level < other.level) {
return -1;
} else if (this.level > other.level) {
return 1;
}
// alphabet not larger or smaller, that means equals
// compare the number part
if (this.sublevel< other.sublevel) {
return -1;
} else if (this.sublevel> other.sublevel) {
return 1;
} else { // alphabet and number part are all equals
return 0;
}
}
}
if you can understand what's going on here, then there should be no problem implementing your problem. (Of course there is shorter and cleaner way to implement this. However I think what you need is to learn the basics first)
So your class is Time and i assume it has 2 variables one for minutes and one for seconds. What you need to compare is the t1.minutes to t2.minutes and the t1.seconds to t2.seconds. Your code however is missing a lot of parts and it can't really help us answer your question correctly.
You can use the comparator interface on your Time class.
Doc: http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
There should be plenty of examples online.