I am trying to read some Java code from a tutorial, I don't understand the line:
public Weatherman(Integer... zips) {
I don't understand what the ... represents if it was just (Integer zips) I would understand that there is a variable of class Integer called zips. But the ... are confusing me.
Those are "varargs," syntactic sugar that allows you to invoke the constructor in the following ways:
new Weatherman()
new Weatherman(98115);
new Weatherman(98115, 98072);
new Weatherman(new Integer[0]);
Under the covers the arguments are passed to the constructor as an array, but you do not need to construct an array to invoke it.
That’s a “vararg”. It can handle any number of Integer arguments, i.e.
new Weatherman(1);
is just as valid as
new Weatherman();
or
new Weatherman(1, 7, 12);
Within the method you access the parameters as an Integer array.
You are seeing the varargs feature of Java, available since Java 1.5.
zips is an array of Integer inside the constructor, but the constructor can be called with a variable number of arguments.
From the Java tutorials:
You can use a construct called varargs to pass an arbitrary number of values to a method. You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually (the previous method could have used varargs rather than an array).
To use varargs, you follow the type of the last parameter by an ellipsis (three dots, ...), then a space, and the parameter name. The method can then be called with any number of that parameter, including none.
public Polygon polygonFrom(Point... corners) {
int numberOfSides = corners.length;
double squareOfSide1, lengthOfSide1;
squareOfSide1 = (corners[1].x - corners[0].x)*(corners[1].x - corners[0].x)
+ (corners[1].y - corners[0].y)*(corners[1].y - corners[0].y) ;
lengthOfSide1 = Math.sqrt(squareOfSide1);
// more method body code follows that creates
// and returns a polygon connecting the Points
}
You can see that, inside the method, corners is treated like an array. The method can be called either with an array or with a sequence of arguments. The code in the method body will treat the parameter as an array in either case.
If I remember good it is used when there is a variable number of parameters
Related
According to Oracle Documentation, the String::compareToIgnoreCase is also a valid method reference, my question is that compareToIgnoreCase is not a static method, in other words, compareToIgnoreCase must be attached to a specific String instance. So how does JDK know which instance of String I refer when I use String::compareToIgnoreCase ?
Consider the following example using toUpperCase which is also an instance method.
It works in this case because the Stream item that is being handled is of the same type as the class of the method being invoked. So the item actually invokes the method directly.
So for
Stream.of("abcde").map(String::toUpperCase).forEach(System.out::println);
the String::toUpperCase call will be the same as "abcde".toUpperCase()
If you did something like this:
Stream.of("abcde").map(OtherClass::toUpperCase).forEach(System.out::println);
"abcde" is not a type of OtherClass so the OtherClass would need to look like the following for the stream to work.
class OtherClass {
public static String toUpperCase(String s) {
return s.toUpperCase();
}
}
String::compareToIgnoreCase is not used such as str1.compareToIgnoreCase(str2) would be.
It actually is used as a comparator.
E.g. you could compare it to
Arrays.sort(someIntegerArray, Collections.reverseOrder())
but in this case it would be
Arrays.sort(someStringArray, String::compareToIgnoreCase)
It is like there is an additional parameter, the actual instance, involved.
Example for String::compareToIgnoreCase:
ToIntBiFunction<String, String> func = String::compareToIgnoreCase;
int result = func.applyAsInt("ab", "cd"); // some negative number expected
We get a ToIntBiFunction - a two parameter function returning int - since the result is an int, the first parameter correspond to this of compareToIgnoreCase and the second function parameter is the parameter passed to compareToIgnoreCase.
maybe a bit easier:
ToIntFunction<String> f = String::length; // function accepting String, returning int
int length = f.applyAsInt("abc"); // 3
length does not accept any parameter, but the first argument of the function is used as the instance length is called on
The examples above are very abstract, just to show the types involved. The functions are mostly used directly in some method call, no need to use an intermediate variable
I am looking to add a function to a program where I use static variables to create a list of all the times the driver has used the constructor, using names. What I need to know is this, is there a way, in java, to access what the reference variable is (as a string) to add it to the list?
Pseudocode:
public ClassName
String static list = "";
Public ClassName (parameters){
list += getReferenceVariable();
}
The getReferenceVariable is what I'm asking if anyone knows a way to do that
If I understand you correctly, you want to keep a list of all the times the constructor was called, and save the names of the currently-being-created variable? Because the "Reference variable" is none when you use the constructor, since you call the constructor with a new MyClass(), and not some obj.MyClass().
If, however, you simply want to know who called you (As a stack trace is), you can simply, as written in this thread (no pun intended), use
Thread.currentThread().getStackTrace(), and then choose the desired stack frame (Probably 2, since The first element (index 0) in the array is the java.lang.Thread.getStackTrace method, the second (index 1) is the constructor, and 2 is where the constructor was called from), where you can get (for example) the name of the source file that this stack trace corresponds to. Documentation of getFileName()
Since I haven't tried it on my end (not possible at the moment), I give you code to use with caution:
public class MyClass(){
MyClass(){
callerName = Thread.currentThread().getStackTrace()[2].getFileName();
... // anything here
}
}
I have the following code:
public class BiPredicateTest {
public static void main(String[] args) {
BiPredicate<List<Integer>, Integer> listContains = List::contains;
List aList = Arrays.asList(10, 20, 30);
System.out.println(listContains.test(aList, 20)); // prints true magically?
}
}
In the statement listContains.test(aList, 20), how is it that the method "contains" is getting called on the first argument and the second argument is passed in as a parameter? Something equivalent to:
System.out.println(aList.contains(20));
In other words, how does the statement listContains.test(aList, 20) get translated to aList.contains(20)?
Is this how java 8 BiPredicate work? Could someone explain how the magic is happening (with some references)?
This is not a duplicate post. This differs from "What does “an Arbitrary Object of a Particular Type” mean in java 8?" in that its not explicitly passing method reference around. It is very clear how method reference is being passed around in the post you reference. The array instance on which the method is being called is passed as an argument to Arrays.sort(). In my case, how the method "contains" is being called on aList is not apparent. I am looking for a reference or explanation as to how its working.
It seems some individuals prefer to down vote instead of provide reference or explanation. They give the impression that they have knowledge but refuse to share it.
BiPredicate is an interface which has only one method, test.
public interface BiPredicate<A,B> {
boolean test(A a, B b);
}
Interfaces which have only one method are called functional interfaces. Previous to Java 8, you would often times have to implement these interfaces using an anonymous class, just to create a wrapper for a certain method call with the same signature. Like this:
BiPredicate<List<Integer>,Integer> listContains = new BiPredicate<>() {
#Override
public boolean test(List<Integer> list, Integer num) {
return list.contains(num);
}
};
In Java 8, method references were added, which allowed for a much shorter syntax and more efficient bytecode for this pattern. In a method reference, you can specify a method or constructor which has the same signature as the type arguments for the interface. When you make a method reference using a class type, it assigns the class type as the first generic argument of the functional interface being used. This means whatever parameter which uses that generic type will need to be an instance of the class.
Even if the instance method normally doesn't take any parameters, a method reference can still be used which takes an instance as the parameter. For example:
Predicate<String> pred = String::isEmpty;
pred.test(""); // true
For more information, see the Java Tutorial for Method References.
Am having some arguments say (String a, Treeset b, Set c)
and I try to get the class by arguments[i].getClass(); of the above arguments..
is Iit possible to get the class of the interface <Set>.
For example:
Class[] argumentTypes = new Class [arguments.length];
for (int i = 0 ; i < arguments.length ; i++)
{
argumentTypes[i] = arguments[i].getClass();
}
The code you've given will find the classes of the arguments (i.e. the values provided to the method) - but those can never be interfaces; they'll always be concrete implementations. (You can never pass "just a set" - always a reference to an object which is an instance of an implementation of the interface, or a null reference.)
It sounds like you want the types of the parameters - which you'd get via reflection if you absolutely had to, finding the Method and then getting the parameters from that with getParameterTypes. But given that you're within the method, you already know the parameter types, because they're at the top of the method... I'm not sure the best way of finding "the currently executing" method, if that's what you're after.
If you're just trying to get the class associated with Set, you can use Set.class of course. But again, it's not really clear what you're trying to do.
EDIT: Okay, judging from your comment, there are some logical problems with what you're trying to do. Going from the values of arguments to which method would be invoked is impossible in the general case, because you've lost information. Consider this, for example:
void foo(String x) {}
void foo(Object y) {}
foo("hello"); // Calls first method
foo((Object) "hello"); // Calls second method
Here the argument values are the same - but the expressions have a different type.
You can find all methods which would be valid for the argument values - modulo generic information lost by type erasure - using Class.isAssignableFrom. Does that help you enough?
Note that you'll also need to think carefully about how you handle null argument values, which would obviously be valid for any reference type parameter...
You can use http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getInterfaces()
You will get the class what the caller provided.
I mean,in below class you will get HashSet.
Set set=new HashSet();
System.out.println(set.getClass());
You can do this in two ways given below
Set s = new //any class that implements it for example HashSet or TreeSet etc.;
s.getClass().getName(); //This will return the name of the subclass which is refered by s.
or if in other way can do it
Set s = null;
s.getClass();//This causes NullPointer Exception
The following java code will not execute.
class A{
int sqrt(int a)
{
}
float sqrt(int a)
{
}
int a1 = sqrt(a);
float b1= sqrt(b);
}
In interview i was asked by a question that why java compiler does not check the data type and call that method accordingly. What is the reason?
Those methods have the same signature (identifier + parameter list), which is illegal.
The reason the compiler won't allow this is that it is not always possible to infer the desired data type. For example, Java supports "boxing" of native values into objects, so you should be able to do this:
ArrayList<Object> list = new ArrayList<Object>();
list.add(a.sqrt(4));
In code like this, it would be literally impossible for the compiler to figure out whether you wanted to call the method that returns a float or the method that returns an int.
If you have 2 methods with same name and same parameters of same data types then java compiler will not even let you compile the code. It should say that method "sqrt" is already defined. So it's illegal in java.
I asked when i was a beginner in programming. . Let me give the answer myself. It always checks the return type of method and call that method accordingly . In case of
int a1 = sqrt(a);
it will call method whose return type is integer.