This question already has answers here:
What is the ellipsis (...) for in this method signature?
(5 answers)
Closed 7 years ago.
I was looking through some code and saw the following notation. I'm somewhat unsure what the three dots mean and what you call them.
void doAction(Object...o);
Thanks.
It means that this method can receive more than one Object as a parameter. To better understating check the following example from here:
The ellipsis (...) identifies a variable number of arguments, and is
demonstrated in the following summation method.
static int sum (int ... numbers)
{
int total = 0;
for (int i = 0; i < numbers.length; i++)
total += numbers [i];
return total;
}
Call the summation method with as many comma-delimited integer
arguments as you desire -- within the JVM's limits. Some examples: sum
(10, 20) and sum (18, 20, 305, 4).
This is very useful since it permits your method to became more abstract. Check also this nice example from SO, were the user takes advantage of the ... notation to make a method to concatenate string arrays in Java.
Another example from Variable argument method in Java 5
public static void test(int some, String... args) {
System.out.print("\n" + some);
for(String arg: args) {
System.out.print(", " + arg);
}
}
As mention in the comment section:
Also note that if the function passes other parameters of different
types than varargs parameter, the vararg parameter should be the last
parameter in the function declaration public void test (Typev ... v ,
Type1 a, Type2 b) or public void test(Type1 a, Typev ... v
recipientJids, Type2 b) - is illegal. ONLY public void test(Type1 a,
Type2 b, Typev ... v)
It's called VarArgs http://www.javadb.com/using-varargs-in-java. In this case, it means you can put multiple instances of Object as a parameter to doAction() as many as you wants :
doAction(new Object(), new Object(), new Object());
Related
I've made a Matrix class in java and I wanted to add some init() functions.
I need one that takes as the first argument a Function object, and the function's arguments if needed as the second.
I have encountered two problems:\
If the function only takes one argument, the notation init(Function<> func, Object... args) gives an error is thrown when compiling: incompatible types: java.lang.Object cannot be converted to int.
If I work around that (by calling init(FuncClass::Func, 7, null), which doesn't seem such a good idea), I have an error thrown at func.apply(args) because incompatible types: java.lang.Object cannot be converted to int.
The current function definition is this:
public void init(Function<Object, Double> function, Object... args){
for (int i = 0; i < this.rows; i++) {
for (int j = 0; j < this.cols; j++) {
this.data[i][j] = function.apply(args);
}
}
}
The data object is defined as:
double[][] data = new double[rows][cols];
Edit: since it came up in the comments, I noticed that the title can be misunderstood.
The problem isn't no input at all. It shouldn't have a predetermined input. I mean, it could be defined as func() as well as func(double min, double max, Random rn, double seed).
If you can suggest a more explanative title, please do.
After some research, I found out that:
The interface Function<T, R> is specifically designed for a 1-input 1-output function.
In the parent package (java.util.function) there is no interface for a function that takes more than 1 argument. (Edit: as pointed in the comments, there also are interfaces that take two arguments. Still, that doesn't solve my problem.)
The solution might be to force the function given as parameter to accept an array of objects as the only argument, then parse them as required.
An example of this would be something like:
public static double func(Object[] args){
int a = (int) args[0];
int b = (int) args[1];
return (double) a * b;
}
(The parsing isn't done in a try-catch block because I want an exception thrown anyway if the wrong args are given to the function)
This question already has an answer here:
why java supports function overloading for primitive data types? [duplicate]
(1 answer)
Closed 5 years ago.
I have a package myPackage which contains 2 classes. First one has 2 public constructors that take a numeric value. First one takes an int and the second one takes Integer. As far as I know they both are the same, just one of them is a primitive type.
When I make an object reference in the other class and run it, in result it calls a constructor that takes the int value.
My question: How it is determined which constructor is called in this case?
P.S. Sorry if this question is too simple. I'm just starting to learn Java.
package myPackage
public class myPackageClass{
public myPackageClass(int var){
System.out.println("Constructor + int value["+var+"]");
}
public myPackageClass(Integer var){
System.out.println("Constructor + Integer value["+var+"]");
}
}
the test file
package myPackage
public class testClass{
public static void main(String ... arg){
myPackageClass var2= new myPackageClass(1);
}
}
}
and the output :" Constructor + int value[1] "
They are not exactly of the same type. 1 is of type int, but new Integer(1) would be of type Integer. So if you would do new myPackageClass(new Integer(1)) the output would be Constructor + Integer value[1]
Other options of passing an Integer instead of int are: new myPackageClass((Integer)1) and new myPackageClass(Integer.valueOf(1))
First it will lookup after one constructor with the same parameter (myPackageClass(int) in your case).
Then, if no constructor is found, then will lookup for one with Box/Unbox parameter ( myPackageClass(Integer) )
You can see the algorithm here : jls-15.12.2
if you create the integer like this : Int i = new Integer(1); The second method will be invoked. If you create the integer like this Interger i = 1; if it is within range -128 ~127 the first method will be invoked else the sencond will be involed. If you use the constrctor directly like this A(1); the first method will be invoked
This question already has answers here:
Overloaded method selection based on the parameter's real type
(7 answers)
Closed 6 years ago.
The following code showed up in a past paper with multiple mistakes (which i have spotted and fixed easily) but what i struggle to understand is the output.
The classes:
import java.util.*;
class Count {
int i, s, o, l, c;
public Count(Object[] objects){
for(int j=0; j<objects.length; j++){
count(objects[j]);
}
}
public void count(Collection x){c++;}
public void count(List x){l++;}
public void count(Double x){i++;}
public void count(Object x){o++;}
public void count(String x){s++;}
public String toString(){
return c + ", " + l + ", " + i + ", " + o + ", " + s;
}
}
import java.util.LinkedList;
public class Test {
static Object[] objects = {new Double(10), new String("Q1"),
new Object(), new LinkedList()};
public static void main(String args[]){
System.out.println(new Count(objects));
for(Object o : objects)
System.out.println(o);
}
}
Generated output:
0, 0, 0, 4, 0
10.0
Q1
java.lang.Object#6d06d69c
[]
I'd appreciate if someone could explain the output with reference to the code.
Side note: the first line of output is what puzzles me. The other bit i understand.
Last note: This is a unique question regarding the output. It is not a duplicate of any question (to the best of my knowledge - the link to the 'possible duplicate' is regarding method overloading not "how is this output produced?" and the outcomes in both questions are unique to each other) so a precise answer would be helpful. Thanks.
for(int j=0; j<objects.length; j++){
count(objects[j]);
}
corresponds to
public void count(Object x){o++;} only
because the argument you're passing when you call count(objects[j]) is an object. You're calling a count function which has an object as parameter, and that's what Java is doing for you.
The number of objects in objects[] is 4. Hence count(Object x) gets called 4 times.
As regards the other integers, they are initialized by default to 0, and hence you see 0.
That's why you see 0 for all variables except o.
public Count(Object[] objects){
for(int j=0; j<objects.length; j++){
count(objects[j]);
}
In these lines you're creating an array of elements in which each element is of type Object itself (it's the class from which every other class inherits). So output of counting objects of type Object in array shouldn't be a surprise.
(Counting is held by overloaded methods. When you call counting function the one that is chosen must have the most suitable type. Hence, counting with Object type as a parameter is picked.)
0, 0, 0, 4, 0
Next, you're creating new array of Objects, initializing each element of the array with different type.
static Object[] objects = {new Double(10), new String("Q1"),
new Object(), new LinkedList()};
It's possible because of upcasting. As I mentioned before, every element inherits from Object class, so every object in your program is in fact Object. Using mechanism of polymorphism you're program can now "deduce" the real type of elements in your array. Namely, you can see it here
for(Object o : objects)
System.out.println(o);
where Java is printing information obtained dynamically. Hence, double is printed as double, string as string, object itself doesn't have more sensible toString() method than printing its inner "name"(by the way this is the field each object of type Object has) and of course empty link list is no more than [].
One of your problems lies here:
public void count(Collection x){c++;} // never called, init to 0
public void count(List x){l++;} // never called, init to 0
public void count(Double x){i++;} // never called, init to 0
public void count(Object x){o++;} // called 4 times, result is 4
public void count(String x){s++;} // never called, init to 0
You never initialize any of the variables (c, k, i, o, s) so I believe the int type is auto initialized to 0. Then the next time it is called it will increment. So end result is:
0, 0, 0, 4, 0 //
Now the rest:
10.0 // 10.0 because that was value specified when Double was created
Q1 // Q1 because that was the String value when it was created.
java.lang.Object#6d06d69c // memory address of where Object is
[] // initialized to empty list []
The first line outputs the number of Collections, Lists, Doubles, Objects, Strings passed to the constructor of the Count instance in the main method of the Test class, since all of the Count classes only accept one parameter and the count variables are not static four of these will always be zero.
The next four lines print the four objects in the static objects array. This is effectively just printing the results of each objects toSrting() method.
This question already has answers here:
Can a main method in Java return something?
(6 answers)
Closed 8 years ago.
class Half {
public int evaluate(int arg) {
return arg/2;
}
}
public class Box {
public static int [] main (int[] arrIn) {
int[] arrOut = new int[arrIn.length];
Half func = new Half();
for (int i=0; i< arrIn.length; i++)
arrOut[i] = func.evaluate(arrIn[i]);
return arrOut;
}
}
So contents of arrOut are the elements in arrIn divided by two.
I want to take integer array from command line arguments and print array with new contents to screen.(I don't want to take it as string values then convert to int and blah blah)
Is there any way to take direct integers as arguments?
Secondly the above code gives an error.(Obviously)
Error: Main method not found in class Box, please define the main method as:
public static void main(String[] args)
Which brings me to my next question.
Should it always be public static void main(String[] args)? Can't it be public static int main with some arguments other than string type?(Don't explain the static part.. As per my understanding main method needs to be invoked without an object which is why it is static. but if it is forced(somehow) to return an integer, where will it return it?(I mean to which method? or will it directly print to the screen?)I know it doesn't print to the screen (duh!) but then where is the control returned basically after main method finishes execution?
Should it always be public static void main(String[] args)?
Yes, if you want it to act as an entry point.
Can't it be public static int main with some arguments other than string type?
No. Section 12 of the JLS explains JVM start-up, and includes this in 12.1.4:
Finally, after completion of the initialization for class Test (during which other consequential loading, linking, and initializing may have occurred), the method main of Test is invoked.
The method main must be declared public, static, and void. It must specify a formal parameter (ยง8.4.1) whose declared type is array of String.
Basically, the only bits which are optional are:
The name of the parameter
Whether you make it a varargs parameter or not
You can overload the method if you want, providing extra main methods with different parameter types and possibly a return value - but only the void one with a String[] parameter will be treated as an entry point.
I want to take integer array from command line arguments and print array with new contents to screen.(I don't want to take it as string values then convert to int and blah blah) Is there any way to take direct integers as arguments?
No. You have to do it yourself. It's pretty trivial though:
int[] integers = new int[args.length];
for (int i = 0; i < args.length; i++)
{
integers[i] = Integer.parseInt(args[i]);
}
First thing first:
This must always be public static void main(String[] args)
Second to read integer directly, use:
Scanner in = new Scanner(System.in);
int num = in.nextInt();
Say I had a function like this
public static boolean test(int a, int b)
is there some sort of way to access the parameters in some sort of array somewhere? The reason why is i have a function with a lot of parameters but i want to get them all through a for loop so I want to be able to do something like
for(int i; i < 3; i++) test.args[1] do stuff
Are you asking can you pass an array as a parameter? If so then the answer is yes. Below I pass an array of doubles as a parameter to a method.
public void meth1 (double[] myList){
for(int i =0; i<myList.length; i++){
//Process entries here
}
}
Java supports "varargs" - see Arbitrary Number of Arguments:
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 [and accepting] an array manually ..
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.
For instance, in this case that might look like like:
public static boolean test(int... args) {
// now args, a variable of type int[], can be accessed
for(int i; i < args.length; i++) {
doStuff(args[i]);
}
}
This is exclusive of individually named parameters and as such there is no way to enforce the multiplicity in the type system - the above method will accept 0..n integers.
As far as individual parameters: they can only be accessed by bound identifier name and there is no "table lookup" available at runtime. A collection could be built/used internally, of course:
public static boolean test(int a, int b) {
int args[] = {a, b};
// yay, now we got an array of argument values and the method
// must be invoked with exactly 2 arguments
}