I have a class that calculates the mean of an ArrayList, and I'm wondering whether I have it set up correctly? I am still very new to Java, so what I want to end up with is just to take an ArrayList as a parameter, and return it within the main method using:
StatCalc stats = new StatCalc(someArrayList);
System.out.printf("Mean of someArrayList is: %.3f\n", stats.getAverage());
Here is the StatCalc class
public class StatCalc {
//declare inst variables & method
private double average = 0;
private double meanCalc(ArrayList<Double> myList) {
double sum = 0;
if (!myList.isEmpty()) {
for (Double element : myList) {
sum += element;
}
}
return sum / myList.size();
}
//Constructor
public StatCalc(ArrayList<Double> myList) {
double average = meanCalc(myList);
this.average = average;
}
//getter
public double getAverage() {
return average;
}
}
I am just wondering is this is how it's 'supposed' to be done in Java, as before I had the meanCalc method inside the constructor, which worked but I thought was bad practice?
In your constructor, you are declaring average as constructor-scoped.
Just remove double from: double average = meanCalc(myList);
That will assign your instance field, instead of a variable with the same name inside your constructor.
In turn, the getAverage() method will return instance field average after it's been assigned, instead of its default value as unassigned, which is 0.0.
In short:
//Constructor
public StatCalc(ArrayList<Double> myList) {
average = meanCalc(myList);
}
Final note
If you are delivering a functionality that only depends on the parameters given, you can probably do without creating an instance of your class.
You could simply have a static method returning double and taking a List<Double> as parameter.
FYI, under java 8+, all your code can be replaced by only one line :
List<Double> list = new ArrayList<>();
[...]
OptionalDouble average = list.stream().mapToDouble(Double::doubleValue).average();
Related
I am new to Java and I need some clarification how to approach an issue.
I have a class Epicycle, defined below:
public class Ts_epicycle {
private double epoch;
private double[] tle = new double[10];
}
In another class, Refine I am calling a method that requires the tle array:
// create an instance of Epicycle
Epicycle e = new Epicycle();
methodExample(keps1, keps2, e.tle);
In methodExample, I would be setting the array values for tle
1) What is best way for creating getters/setters for the tle array? (and for the other variable too).
2) In the methodExample, I need to pass in the argument for the whole tle array rather than any particular index of it. How would I go about this.
Apologies if i'm not making it clear.
In fact an interesting question:
In order that altering entries in the gotten array does not alter the original object,
you would need to return a copy of the array. Not so nice.
public class TsEpicycle {
private double epoch;
private double[] tle = new double[10];
public double[] getTLE() {
return Arrays.copyOf(tle, tle.length);
}
}
Alternatively you could use the List class instead of an array:
public class TsEpicycle {
private double epoch;
private List<Double> tle = new ArrayList<>();
public List<Double> getTLE() {
return Collections.unmodifiableList(tle);
}
}
This does not make a copy, but simple disallows at run-time to alter the list.
Here the inefficiency is in the Double objects wrapping doubles.
The best might be to use the new Stream class: for iterating through the doubles:
public class TsEpicycle {
private double epoch;
private double[] tle = new double[10];
public DoubleStream getTLE() {
return Stream.of(tle);
}
}
As a general best practice every field in a class that you need to access from another class should be provided with a getter and (if the object is intended as mutable) a setter.
As well explained by Joop Eggen in his answer is usually a good practice to return a copy or a proxy (for example a List/Collection referencing the array), in order to preserve the state of the original array.
If you want to only allow users to edit the array one at a time, then you can add the synchronized keyword to the method signature. Accessing an array is already thread safe so you don't need anything there
For example:
double getTle(int index) {
return tle[index]
}
synchronized void setTle(int index, double value) {
tle[index] = value;
}
This only allows the method to be called once at a time
your array is an object like any other object in java .
// to declare and initialize your array
private int[] st = new int[10];
//getter and setter
public int[] getSt() {
return st;
}
public void setSt(int[] st) {
this.st = st;
}
//for the last method u can use
public void method(int value)
{
for(int i = 0 ; i<st.lenght ; i++){
st[i] += value; // for exemple
}
Okay so don't get turned off by the fact that I want homework help.
Anyways, I don't want to explain the entire project for this little bit of help, but I'll just list some rules, and what I did with them. They're in weird order and they don't make complete sense. And there are many ways to do this probably, and I simply don't know what is what.
So here's the rules I'm confused about:
Three fields, a String for name of the purchase, int for units purchased, and a double for cost per unit.
So I made this:
private String purchase = "";
private int unitsPurchased = 0;
private double costPerUnit = 0;
Then, next rule:
Standard accessors and modifier methods for each field, so I made this:
//Accessors
public String purchase(){
return purchase;
}
public int unitsPurchased(){
return unitsPurchased;
}
public double costPerUnit(){
return costPerUnit;
}
//Modifiers
public void setPurchase(String purchase){
this.purchase = purchase;
}
public void setunitsPurchased(int unitsPurchased){
this.unitsPurchased = unitsPurchased;
}
public void setCostPerUnit(double costPerUnit){
this.costPerUnit = costPerUnit;
}
Then this: Negative values are not allowed, so change those to zero in all cases.
Wasn't sure if that meant to do anything, so I continued on.
Then this: Constructor to initialize these three fields (String, int, double) in that order.
So I did this:
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
}
Then this rule: Constructor overload, (String, double) assumes the int quantity is zero.
I didn't know if that meant anything, so once again I skipped it
Then this rule: Default constructor that assumes name is “” and numbers are zero, must call the three argument constructor.'
Now I'm just confused. So first of all, I would like to know if my code seems right. I don't think I need to explain the backstory of the program to do that. Then, I would love to know what to do about that last rule, because it says "must call the three argument constructor" am I supposed to use "this"? I didn't know where to go and I've tried a couple ideas but I don't think it works. I can't test to see if it's right either, given there's not really anything to test. Thanks so much to anyone who helps.
Here's just everything I've written:
public class Purchase {
private String purchase = "";
private int unitsPurchased = 0;
private double costPerUnit = 0;
//Accessors
public String purchase(){
return purchase;
}
public int unitsPurchased(){
return unitsPurchased;
}
public double costPerUnit(){
return costPerUnit;
}
//Modifiers
public void setPurchase(String purchase){
this.purchase = purchase;
}
public void setunitsPurchased(int unitsPurchased){
this.unitsPurchased = unitsPurchased;
}
public void setCostPerUnit(double costPerUnit){
this.costPerUnit = costPerUnit;
}
//Default constructor
public Purchase(){
purchase = "";
unitsPurchased = 0;
costPerUnit = 0;
}
//first constructor
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
}
//constructor overload
//Default constructor
}
You don't really need that but just in case. That's all a mess, not sure what I'm writing. But thanks to anyone that helps.
Starting with the first rule you didn't understand:
Negative values are not allowed, so change those to zero in all cases.
This is referring to the setter methods you wrote, and it means that if someone calls setUnitsPurchased with a negative number as a parameter, you only set unitsPurchased = 0.
You'll probably want to add an if statement (or ternary, if you're familiar with those) to setUnitsPurchased and setCostPerUnit checking for values below zero.
Wasn't sure if that meant to do anything, so I continued on. Then this: Constructor to initialize these three fields (String, int, double) in that order.
Instead of directly setting the values (like you did):
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
You should probably call your setters, so you don't have to repeat your checks:
this.setUnitsPurchased(initialUnitsPurchased);
// etc.
Constructor overload, (String, double) assumes the int quantity is zero.
If a class has an overloaded constructor, it means that you can initialize it with different amounts and/or types of parameters. You've already overloaded the constructor with an empty constructor and one that takes three arguments.
Simply make another constructor, but with this signature:
public Purchase(String initialPurchase, double initialCostPerUnit)
Default constructor that assumes name is "" and numbers are zero, must call the three argument constructor.
Instead of the default constructor you implemented, you must call the three argument constructor. To call another constructor, use the this keyword, and invoke it like a method, passing in the correct parameters:
this("", 0, 0);
Happy Coding!
Couldn't be more self-explanatory. It writes itself if you can read:
public class Purchase {
private String purchase;
private int numUnits;
private double costPerUnit;
public Purchase() {
this("", 0, 0.0);
}
public Purchase(String purchase, double costPerUnit) {
this(purchase, 0, costPerUnit);
}
public Purchase(String purchase, int numUnits, double costPerUnit) {
this.purchase = purchase;
this.numUnits = (numUnits < 0) ? 0 : numUnits;
this.costPerUnit = (costPerUnit < 0.0) ? 0.0 : costPerUnit;
}
// Leave the rest for you.
}
Three fields, a String for name of the purchase, int for units purchased, and a double for cost per unit.
You got it correct, though there is no need for assigning any values to the data members.
private String purchase;
private int unitsPurchased;
private double costPerUnit;
Standard accessors and modifier methods for each field
You got this correct too.
Negative values are not allowed, so change those to zero in all cases.
You need to change your code to convert neg values to zero. e.g.
public void setunitsPurchased(int unitsPurchased){
if(unitsPurchased < 0)
unitsPurchased = 0;
this.unitsPurchased = unitsPurchased;
}
Constructor to initialize these three fields (String, int, double) in that order.
You got this correct. Though you might want to have this keyword for data members. It just makes it more readable.
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
this.purchase = initialPurchase;
this.unitsPurchased = initialUnitsPurchased;
this.costPerUnit = initialCostPerUnit;
}
Constructor overload, (String, double) assumes the int quantity is zero.
This is simple. you want a constructor with just 2 arguments. It also specifies to have unitsPurchased set to 0.
public Purchase(String initialPurchase, double initialCostPerUnit){
this.purchase = initialPurchase;
this.unitsPurchased = 0;
this.costPerUnit = initialCostPerUnit;
}
Default constructor that assumes name is “” and numbers are zero, must call the three argument constructor.'
Now you know a default constructor does not take any arguments. but the question asks to call the three argument constructor from within this constructor. that can be done using the this() as follows:
public Purchase(){
this("", 0, 0.0);
}
I'm not sure if the title is right but basically I have this piece of code:
for(int i = 0; i < ArrEmployee.size(); ++i){
ArrEmployee.get(i);
double provTax = ProvincialTax.calculateTax(ArrEmployee.get(i));
And this arrayList:
List<Employee> ArrEmployee = new ArrayList<>(); // array for employee objects
And the ProvincialTax class is like this:
public class ProvincialTax extends Deductions { // deductions is an abstract class with the abstract method calculateTax()
public double calculateTax(Employee employee) {
if (employee.getAnnualGrossSalary() < 41495){
return employee.getAnnualGrossSalary()*0.16;
}
else if (employee.getAnnualGrossSalary() < 82985){
return employee.getAnnualGrossSalary()*0.20;
}
else if(employee.getAnnualGrossSalary() < 100970){
return employee.getAnnualGrossSalary()*0.24;
}
else
return employee.getAnnualGrossSalary()*0.2575;
}
}
So basically my arrayList ArrEmployee stores Employee objects that have the variables:
public long EmployeeNumber;
public String EmployeeName;
public String LastName;
public double HoursWorked;
public double HourlyWage;
And the HoursWorked and HourlyWage are used to calculate AnnualGrossSalary used in my ProvincialTax class. With my for loop, I'm trying to calculate the provincial tax for each object inside the ArrEmployee, but it keeps asking me to make the method calculateTax() static, but it's supposed to override an abstract method?
How do I bypass this?
The problem isn't that you should make your method static, the problem is that you're invoking the method as if it was static, which you shouldn't do. The problem is in the line:
double provTax = ProvincialTax.calculateTax(ArrEmployee.get(i));
Which instance of ProvincialTax do you want to invoke it on? Invoke it on that instance.
ProvincialTax taxInstance = ...; // Get an instanceof of ProvincialTax
double provTax = taxInstance.calculateTax(ArrEmployee.get(i));
Without further evidence and the fact that you're not using preferred naming conventions, ProvincialTax.calculateTax appears to be trying to call the calculateTax via the ProvincialTax Class and not a instance of it...
ProvincialTax provincialTax = new ProvincialTax();
for(int i = 0; i < ArrEmployee.size(); ++i){
double provTax = provincialTax.calculateTax(ArrEmployee.get(i));
}
You might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others
I have 20 local parameters in a class and I want to know the efficient way to get the maximum value and total sum among all the parameters. Thank you in advance!
my code is something like
public class EntityOfTheQuery{
double value1;
double value2;
...
double value3;
// this is the function I need
public void maxValue(){
}
}
public double maxValue(){
double[] a = {value1,value2,...,value20};
List b = Arrays.asList(ArrayUtils.toObject(a));
return Collections.max(b);
}
You could do it.
Take a array of size 20 instead of 20 different vars.
double[] value = new double[20];
public double maxValue(){
Arrays.sort(value);
return value[value.length-1];
}
This can be done by reflection. The following code converts each property of the class into an double and compares it to the others.
public class MyClass {
double value1;
double value2;
double value3;
double getMax() throws IllegalArgumentException, IllegalAccessException {
double max = Double.MIN_VALUE;
for (Field field : this.getClass().getDeclaredFields()) {
if(max < (double)field.get(this)) {
max = (double)field.getDouble(this);
}
}
return max;
}
}
NOTE: You have to ensure that each property can be casted into a double value.
If the maxValue method is called very frequently I would suggest to build your logic in the setter ie define all fields as private/protected and then also define a variable maxValue. Your setter logic would look something like this.
setValue1(double value1){
if( getValue1() == maxValue() && value1 < maxValue()){
//.. Check each of value1 .. 20 for the max Value and Assign if
}else if(value1 > maxValue()){
maxValue = value1;
}
}
This would be more efficient even if you are using an array, as you need to scan the entire array/fields only when the value you are setting is less than the current max value and the maxValue is same as the current value (another optimization when using the array would be to store the index of the maxValue and then scan the entire array only when you are reducing the field value and it is the current maxValue field.
In the following code the method array1 won't return the avarage because its return type is void.
I know what void means but can someone explain to me what is a void result type and how to make this method return the avarage:
public class JavaApplication4 {
public static void main(String[] args) {
int[] a = {1,2,3,4};
double result = array1 (a);
}
public static array1 (int[] b) {
double avarage;
int total = 0;
for (int x:b) {
total += x;
}
avarage = total / b.length;
return avarage;
}
The "result type" or "return type" is set in the function declaration. It just means what type of data is going to be returned after the function is called. Your function should look like:
public static double array1(int[] b) {
double average;
int total=0;
for(int x:b){
total +=x;
}
average = (double) total/b.length;
return average;
}
This will return the value of average after the function is done. So result will hold the same thing as the final value of average after the function completes.
You need to declare array1 as returning double. Change its declaration to:
public static double array1(int [] b ) {
A void function -- void array1(...) -- does not return a value.
Note that there's another error in your code:
avarage = total / b.length;
The above uses integer division, meaning that the result is truncated to integer, and only then converted to double. To fix, change the line to:
avarage = total / (double)b.length;
A return type of void means that a method doesn't return anything. This is useful when you want to preform an operation on an array, but there isn't any value associated with the operation. For example, say that you wanted to swap the first and last element in an array, you could write some method like this (ignore the necessary error checking)
public void swapArrayLocs(int[] swapping){
int temp = swapping[0];
swapping[0] = swapping[swapping.length - 1];
swapping[swapping.length - 1] = temp;
}
When you call this method, you're not expecting any sort of result from it, you're expecting your program to just take care of business and continue executing.
In this case, you actually want your array1(int[]) method to make its available to the rest of the program. You do this by specifying the return type of the function, which tells the rest of the program what type of information you expect that function to return. In your case, you'd do this by changing your method declaration to.
public static double array1(int[] b){
//the same method body
}
Note how in this case the word double is inserted after static. This tells the calling function that when it executes array1, the method will give back a value of type double. Contrast this with what you had before which said that the method would not give back any type of information.