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.
Related
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 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();
Suppose there is the enum declaration somewhere in code:
enum Colors { RED(100), BLUE(200); }
Can I get the lowest/highest index value for that particular enum type presuming I am not aware of the declaration? Is it possible in java?
Example:
int lowIndex = Colors.minIndex(); // should return 100
Thanks everyone. So there are no implicit methods to query for min/max defined integer value. I'll have to iterate through the enum values and determine it from there as you have described.
You'll have to iterate over the enum set:
for (Color p : Color.values()) {
// keep track of min "index"
}
Remember that an enum is essentially collection of predefined object instances. RED(100) is calling the Color(int value) constructor. That said, I could make a color enum with values defined like this:
RED("best", 14, 3.33546)
Hence, the logic for finding the minimum "index" will be different case by case.
With index do you mean the ordinal or the integer values given in the enum ?
Anyways this is a simple example that may help you:-
enum Mobile {
Samsung(400), Nokia(250),Motorola(325);
int price;
Mobile(int p) { //values in brackets are set to price property in enum
price = p;
}
int showPrice() {
return price; //you have to declare methods in enum to return value, there is no predefined function like returnValue()
}
}
public class EnumDemo {
public static void main(String args[]) {
System.out.println("CellPhone List:");
for(Mobile m : Mobile.values()) {
System.out.println(m + " costs " + m.showPrice() + " dollars");
}
Mobile ret = Mobile.Samsung;
System.out.println("The ordinal is = " + ret.ordinal());
System.out.println("MobileName = " + ret.name());
}
}
Note that the java.lang.Enum.ordinal() method returns the ordinal of the enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero).
And the output is:-
CellPhone List:
Samsung costs 400 dollars
Nokia costs 250 dollars
Motorola costs 325 dollars
The ordinal is = 0
MobileName = Samsung
You can't override an enum's 'index'. What's happening here is that the Colors enum has a constructor that takes an int as a parameter. It's up to the implementation of the constructor to store that value.
You could maintain a static map of these values, updated by the enum constructor, that could be queried for min/max values.
Alternatively you could just look over all the enums every time looking for the min/max:
int max = Integer.MIN_VALUE;
for (Colors c in Colors.values())
max = Math.max(c.getIndex(), max);
What about this? It "caches" the value when the enum is loaded.
public enum Color {
RED(100),
BLUE(200);
public final int val;
private Color(int val) {
this.val = val;
if (Dummy.maxColor == null || Dummy.maxColor.val < val) {
Dummy.maxColor = this;
}
}
// This seems to be needed because you can't access static fields in enum constructors
private static class Dummy {
private static Color maxColor = null;
}
public static Color getMaxColor() {
return Dummy.maxColor;
}
}
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.
I had a little problem with casting Java long type to Enum type and can't find a solution how to do that.
Here is what I'm using :
public enum DataType {
IMAGES(1),
VIDEOS(2);
private int value;
private DataType(int i){
this.value = i;
}
}
and I need to do something like this:
DataType dataType;
String thiz = "1";
long numb = Long.parseLong(thiz);
dataType = numb;
The error that I get says:
Convert numb to DataType or convert dataType to long.
Second Scenario:
I have this :
static String[] packetType;
String tmp=incomingData.toString(); // where incomingData is byte[]
int lastLoc = 0;
int needsSize = packetFieldSizes[tmpCurrentField-1]; // where packetFieldSizes,tmpCurrentField are integers.
thiz=tmp.substring(lastLoc, needsSize);
packetType=thiz; // packetType = thiz copy; where thiz is the same as used above.
I tried to convert thiz to String[] and use valueOf,but
Any suggestions how to get the thinks to work?
Thanks in advance!
Enum already provides a unique integer for each of it's instances. Check out ordinal(). (Note that it's zero-based though.)
If you need to go from a long to a DataType you can do
DataType dataType;
String thiz;
long numb = Long.parseLong(thiz);
dataType = DataType.values()[(int) numb];
A complete list of conversions from and to enum constants, strings and integers can be found in this answer:
Conveniently map between enum and int / String
If for some reason you need to assign the numbers yourself and thereby can't use aioobe's good solution, you can do something like the following:
public enum DataType {
IMAGES(1),
VIDEOS(2);
private final int value;
private DataType(int i){
this.value=i;
}
public static DataType getByValue(int i) {
for(DataType dt : DataType.values()) {
if(dt.value == i) {
return dt;
}
}
throw new IllegalArgumentException("no datatype with " + i + " exists");
}
The static method getByValue() searches for the DataType with the provided number.
In addition to #aioobe's answer, you could roll your own getInstance method. This would provide more flexibility, since you wouldn't be dependent on the ordinal.
public enum DataType {
.
.
public static final DataType getInstance(final int i){
for(DataType dt: DataType.values()){
if(dt.value == i){
return dt;
}
}
return null;
}
}
Correct answer from aioobe. Maybe some other concerns ?
You could be better of using int instead of long, for the enum index.
It could be like :
String indexAsString;
int index = Integer.parseInt(indexAsString)-1;
DataType dataType = DataType.values()[index];
Please note the "-1", as arrays are zero-based while your index is one-based.
ordinal() will work if the numbers you are passing to the enum are indexes and not some arbitrary code, like resolution or number of chars in a line.
I'd extends the enum with an accesor method for the value, a resolution index and a static method that resolves a number into a Enum value. Here you go...
public enum DataType {
IMAGES(1),
VIDEOS(2);
private int value;
DataType(int i){
this.value=i;
}
static final Map<Integer,DataType> inverseIndex;
static {
inverseIndex = new HashMap<Integer,DataType> ();
for (DataType dt:DataType.values()) {
inverseIndex.put(dt.getValue(), dt);
}
}
public int getValue() {
return value;
}
public static DataType resolve(int number) {
return inverseIndex.get(number);
}
}
Note that this solution won't work is your map Enum-value is not bijective, so you may only have distinct values for the enums in your enumType.