I´m currently reading through someone else´s code and he has the following two methods:
public static double fac(double d) {
return d <= 0 ? 1 : d * fac(d - 1);
}
public static DoubleUnaryOperator getfun() {
return LamdaTests::fac; // LamdaTests is the classname of this class
}
First of all, i´m currently trying to understand lambda expressions/method references.
I have 2 questions:
1) What does the getFun() method exactly do? It should call the fac(double d) method in this class LambdaTests right? But with which argument and how can the return value be a DoubleUnaryOperator, shouldn´t "LamdaTests:fac" return a double?
2) What would be the equivalent Lamda expression for Lamdatests::fac in this case?
Edit: As far as i know
return LamdaTests::fac;
should be equal to
return x -> fac(x);
But i just dont understand where it gets the argument x from.
getFun doesn't call anything. It just returns a reference to the fac function. You need to call the returned function still to get a result. getFac isn't very useful here, so that may be what's confusing things. In reality, you would just use LamdaTests::fac directly, unless that method was private.
For the latter question, think of it this way:
x -> fac(x)
is a function that takes a double and returns a double. What is fac? It's the same thing: a function that takes a double and returns a double. The argument is just implicit here.
As far as I've researched, there's no way to match a String with a variable. probably I'm using the wrong word, here's what I mean by matching:
String grade="a";
double a=4.0;
And there's no way to associate the value of String grade with double a.
Similarly, what I want to do is associating value of a String with a method. Maybe I'm on the wrong track, let me briefly explain what I'm trying to achieve:
In the class player, there's a String name() method that returns This.name. There's no graphical design, and the only way for user to communicate with the program is typing. Basically, when person types name, I want name method to be ran. I'm pretty new, and the only way I can think of doing it is using a bunch of if statements, and adding another if statement for each method I add does not sound right to me.
Note: The reason I need String to be associated is because I'm going to use javax.swing.JTextArea to get input from the user, which returns String.
Thanks in advance
Yes. It's called a Map.
Here's some sample code of how to use one:
Map<String, Double> map = new HashMap<>();
map.put("grade", 4.0);
double a = map.get("grade");
If you want to store a variety of value types use Map<String, Object>, but you'll have to make unsafe casts when retrieving and using the values returned from get().
Java is not a dynamic interpreted language like Python or Perl.
To associate arbitrary strings with values you should use a Map<String,ValueClass> where ValueClass is the value to associate, such as Integer, Float, BigDecimal or your own value class.
Because grades are usually fixed from A to F, I would use an enum to map each grade to a numeric value:
enum Grade {
A(4.0), B(3.0) // etc...
private double val;
private Grade(double val) {
this.val = val;
}
public double getVal() {
return val;
}
}
Then use Grade.A.getVal() when you need the numeric value of the A grade.
I'm a beginner in Java programming, and I'm trying to make a voting machine program, where you can vote for Republicans or Democrats. My question is, how can I edit my method so I would be able to return two strings with two distinct values?
For example, look at my code all the way in the bottom. It's wrong, but I wanted the tester to be able to print out Democrats: (some number) and Republicans: (some number) in one method. How can I do that?
import java.lang.String;
public class VotingMachine1 {
private double Democrats;
private double Republicans;
public VotingMachine1() {
Democrats = 0;
Republicans = 0;
}
public void voteRepublican() {
Republicans = Republicans + 1;
}
public void voteDemocrat() {
Democrats = Democrats + 1;
}
public void clearMachineState() {
Republicans = 0;
Democrats = 0;
}
//this is where I'm having difficulties. I know its wrong
public double getTallies() {
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
}
No return is necessary there, since you aren't leaving a function. To do what you seem to want to do, just replace that last method with the following:
public void getTallies()
{
System.out.println("Democrats: " + Double.toString(Democrats));
System.out.println("Republicans: " + Double.toString(Republicans));
}
Also, since your votecounts should only ever be integers, there's no reason to declare them as doubles instead of ints.
What you are looking for here is a format string. A format string is used when you know what your output should look like, and only have a few "holes" where unknown data should be filled in. To output your data using format strings, you would use the System.out.format(String, Object...) method:
System.out.format("Democrats: %f\n", Democrats);
System.out.format("Republicans: %f\n", Republicans);
In this case, the %f indicates that a floating-point number (since your variables are declared as double) will be printed instead of the %f. However, you may wish to consider declaring them as int (or long) instead, in which case you would use %d instead of %f in the format strings.
Finally, you ought to change your getTallies() method to return void instead of double, as you are printing the values, not returning them.
Your code and your description are so contradictory, it is not clear that you even know what you are trying to do. I believe that this is the real root of your problems.
Here goes:
public double getTallies()
{
System.out.println("Democrats: ", return Democrats);
System.out.println("Republicans: ", return Republicans);
}
First, your question says that you want to "return two strings with two values" ... but you have declared the method as returning one double.
Next, your code is printing values ... not returning them.
You've also made some major mistakes at the syntactic level, largely (I believe) because you are trying to do contradictory things:
return Republicans is not a valid Java expression, so you can't use it as a argument to the println method.
The println method can't be called with two arguments, as your code is trying to do. There is a zero argument version and a number of one argument overloads ... but no overloads with two or more arguments.
Basically, you need to start by making up your mind about what this method is supposed to do. Is it supposed to:
return the tallies (as two doubles)?
return a string representing the two tallies?
return nothing ... and output the two tallies to standard output?
do something else?
Once you've made up your mind:
code the method to do what you've decided it should do, and
chose a method name that correctly reflects what it is supposed to do. Hint: a method that starts with get is conventionally a "getter" that returns the attribute or attributes themselves ... not a String rendering.
double is a bad choice of type for a vote count too:
You cannot have a fractional vote.
You want to represent vote counts precisely and floating point types (like double) are not precise. (Or at least, not in the sense that you require.)
When you attempt to format or output a double, the resulting character string is likely to include a pesky decimal point ... or worse.
You should use int or long instead of double.
Finally, this is a serious Java style violation, and should get you a significant penalty if your marker is paying attention.
private double Democrats;
private double Republicans;
Variable names in Java should start with a LOWER CASE letter.
A few more random comments:
import java.lang.String; is superfluous as all classes in package java.lang are automatically imported in every Java source file.
Votes can not be fractional. People can't vote 0.75 candidate A, and 0.25 candidate B. If you use integer datatypes (int or long), you will be reflecting this fact better. Also, you will be saving yourself a lot of headache when you start obtaining results like 379857.999999. This is because floating point types have a better range, but worse precision (especially noticeable when working with pure integers).
According to Java usual naming conventions, variable names should start with a lowecase letter.
A better name for function getTallies is printTallies.
For output purposes, it's much better to use string formatting than concatenation. Some advantages are: multiple formats supported, ease of use, and internationalization.
Putting all together:
private int democratVotes;
private int republicanVotes;
public void printTallies() {
System.out.format("Democrats: %,d%n",democratVotes);
System.out.format("Republicans: %,d%n",republicanVotes);
}
In this particular case, votes will be printed with thousand separation (ex: 3,345,623 instead of 3345623). Check Java's Formatting Numeric Print Output tutorial.
Thinking better about it, there are some alternatives where getTallies would effectively be returning some form of value:
1) Make it to return a String with both tallies. It would be hard and inefficient to separate the tallies later, though.
public String getTallies() {
return "Democrats: %,d votes. Republicans: %,d votes.%n".format(democratVotes,republicanVotes);
}
2) Make it to return an array.
public int[] getTallies() {
return new int[2]{ democratVotes, republicanVotes };
}
public int[] getTallies1() { // Same as getTallies, but written step by step.
int[] result= new int[2] ;
result[0]= democratVotes ;
result[1]= republicanVotes ;
return result ;
}
3) Make it to return a class.
public VotingMachineResults getTallies() {
return VotingMachineResults(democratVotes,republicanVotes) ;
}
public static class VotingMachineResults {
private int democratVotes;
private int republicanVotes;
public VotingMachineResults(democratVotes,republicanVotes) {
this.democratVotes= democratVotes ; // `this` required to disambiguate field democratVotes from parameter democratVotes.
this.republicanVotes= republicanVotes ;
}
public int getDemocratVotes() {
return democratVotes ;
}
public int getRepublicanVotes() {
return republicanVotes ;
}
}
As you can see, this class is very similar to VotingMachine1, but it does not accept internal state changes. It is a "value" class.
In Java, you concatenate Strings with the + operator. Proper syntax for what you were trying to do looks like this:
System.out.println("Democrats: " + Democrats);
System.out.println("Republicans: " + Republicans);
A return statement is only used when you want to return some object or value to a method that called your current method. It is not appropriate in this place since you're only passing a value to another method (println()).
ALSO, you need to fix your getTallies() method. Make it return void instead of double since you aren't returning anything.
Here's something completely different: why not override toString()?
Presumably, any instance of VotingMachine1 will apply for all votes that you care about for that instance. That is to say, you don't create a new instance of a VotingMachine1 every time someone casts a vote.
So, what you can do is override the toString() method. We'll also use String.format() to handle the numerical values.
#Override
public String toString() {
// assumes that Democrats and Republicans are declared as int
// since it's pointless to indicate percentages of a vote
return String.format("Democrats: %d\nRepublicans: %d", Democrats, Republicans);
}
Now, whenever you vote, you can use the toString() method to get the information (which is called whenever one does System.out.println(object).
VotingMachine1 voter = new VotingMachine1();
voter.voteDemocrat();
voter.voteRepublican();
System.out.println(voter);
/* This prints:
Democrats: 1
Republicans: 1
*/
A less specific answer to your question would be to return an Object called (say) Votes
public class Vote {
int democratVotes
int republicanVotes
}
and then make your VotingMachine class simply return an instance of this object (suitably changed to make it immutable).
On my project we have created a generic version of this called a Tuple that returns a pair of values in a single object - it has an overloaded toString method for easy printing.
you can return an array with [0] and [1] as key and devide it on the basis of your need..
like
returnArray[0]="first string";
returnArray[1]="second string";
and use it ur way...
With autounboxing, this statement will automatically work:
int myPrimitive = (Integer) doIt();
But if I want to explicitly convert from an Integer to an int here in a single line, where do I have to put the parentheses?
You could do this :
int myPrimitive = (int) (Integer) doIt();
But as you said, auto-unboxing will get that for you.
A bad example to show that chain casts work (don't ever use this code) :
Map notReallyAMap = (Map) (Object) new String();
The thing with chain casts, is that wherever you use it, either the cast is legit, and you can remove intermediaries; or the cast will simply cause a ClassCastException. So you should never use it.
Either the compiler unboxes the Integer for you, or you do it yourself - this cannot be avoided.
So you need to either do
int myPrimitive = ((Integer) doIt()).intValue();
or more simply, change doIt() to return an int since you seem to want to deal with ints rather than (null-able) Integers.
I want to write a conditional statement, depending on whether a variable is an int or double, i.e
if (x is a double)
do stuff
else if(x is an int)
do stuff
else
do stuff
I know this might not be a good idea, but its my only choice for now. Is this possible?
I have no idea how x could be an int or a double without you knowing at compile time, but
void dostuff(int x) {
do stuff...
}
void dostuff(double x) {
do stuff...
}
then
dostuff(x)
will call the appropriate method.
Edited to add:I don't think this question is really what you want, based on your comment to the original question. I'll post a comment on the other question to try and offer some assistance to yoru real issue.
As Bill the Lizard says, you'll know at compile time what type a primitive is:
public void foo(int x, double y){...}
On the other hand, if you're putting your types inside another object, like
Vector v = new Vector();
v.add((int)1);
v.add((double)1.0));
then you're really dealing with objects not primitives. Each primitive has a corresponding class:
int has Integer
double has Double
float has Float
boolean has Boolean
etc.
You can use the instanceof keyword to determine what type you're dealing with (you can do this with any class):
if( x instanceof Double ) {
doDoubleThing();
} else if( x instanceof Integer ) {
doIntegerThing();
} // and so on
I'm guessing you're trying to check if a number has a decimal part or not.
double n;
if(n-floor(n)>0)
it has a decimal part
else
it's an integer
What atk wrote is valid if you have the ability to use two methods. If this isn't an option or you don't want to do this (personally think it might be more readable and less repetitious to have one method and just do an if-else branch, depends on your code), you can use reflection:
Class intClass = Integer.class;
Class doubleClass = Double.class;
if intClass.isInstance(foo)
bar();
else if doubleClass.isInstance(foo)
spam();
else
eggs();
This might not necessarily be the best solution. Just thought you should know about it.