Question is left here because people answered it, my problem was that the version of the API I was using was out of sync with the docs I had....You can in fact do this.
Is there any way to use a 2-d array in Java as an argument for an argument that expects a vararg of arrays?
The function I am trying to call is
public Long sadd(final byte[] key, final byte[]... members) {
and I have a 2-d array of bytes(byte [][] data=blah)
however if I try to call
sadd(key,data);
I get the following compiler error:
(actual argument byte[][] cannot be converted to byte[] by method invocation conversion)
Is there any way to use a 2-d array as a vararg of an array type?
The following works for me. Perhaps you're not doing what you think you're doing?
#Test
public void test_varargs() {
byte[] x = new byte[] { 1, 2, 3};
byte[] y = new byte[] { 0, 1, 2};
assertEquals(9L, sum(x,y));
byte[][] z = new byte[][] { x,y };
assertEquals(9L, sum(z));
}
public long sum(final byte[]... members) {
long sum = 0;
for (byte[] member : members) {
for (byte x : member) {
sum += x;
}
}
return sum;
}
Can you provide more of your code because this compiles for me.
byte[][] data = new byte[1][];
byte[] key = new byte[1];
long sadd = sadd(key, data);
class A {
void show(int[] ax,int[]...arr) {
for (int is : ax) {
System.out.println(is);
}
for (int[] a : arr) {
for (int i : a) {
System.out.println(i);
}
}
}
}
public class abc{
public static void main(String[] args) {
A a = new A();
int[] arr1= new int[]{10,20};
int[][] arr2 = new int[][] { { 10, 20 }, { 20, 20 }, { 30, 20 } };
a.show(arr1,arr2);
}
}
Here I have used 2-d array as var args parameter and a 1-d array as fixed parameter. Refer this code if this can help you! :)
It's not possible since the compiler has no way to infer the two dimensions. When using one-dimensional array you can determine the length of the array as the number of auxiliary arguments (those that are not mandatory).
e.g: Let's say you method definition includes n mandatory parameters and, at runtime, you supply m more arguments. Those m arguments are going to make up the array of auxiliary arguments. The length is m. In case of a two-dimensional array, the compiler has to come up with two dimensions for the array such that: dimension1 * dimension2 = m.
Related
Effective java 2, Item 42 propose an elegant way for a method take at least one argument, and fail at compile time if the input is empty. The code is shown below in the min() method, however I am wondering what is the elegant way to call this method, because now simply passing list will trigger an compiler error.
public class OneOrMoreArgs {
public static int min(int firstArg, int... remaining){
// but then how do you call the function with a int[] ?
int _min = firstArg;
for(int x: remaining){
if(_min < x ){
_min = x;
}
}
return _min;
}
public static int sum(int... list){
int s = 0;
for(int a: list){
s += a;
}
return s;
}
public static void main(String []args){
int[] list = {1,2,3,4,5};
System.out.println(OneOrMoreArgs.sum(list));
System.out.println(OneOrMoreArgs.min(list));
}
}
Well, the elegant way to call it would be to do
OneOrMoreArgs.min(1, 2, 3, 4, 5);
If you need to pass in an array, you could add an additional method signature like this:
public static int min(int[] args){
if (args == null || args.length < 1) {
throw new IllegalArgumentException("... some error message...");
}
return min(args[0], Arrays.copyOfRange(args, 1, args.length));
}
It needs to be noted that:
This solution is inefficient as it requires the array to be copied.
The check is executed at runtime instead of compile time, so you lose the benefits of the solution proposed by Item 42.
It looks like for your use case, you're better off just declaring a method that takes an array parameter, like the sum() in your example.
I tried to make a parameter for an array for a method, but it always comes up with an error.
public void methodExample1() {
int array1[] = new int[4]
}
public void methodExample(Array array1[]) {
System.out.println(array1[0]);
}
But it always says there's an error in my parameter. Is there any way to do this?
Try this:
public void methodExample(int[] array1)
Explanation: The type is the same that you used for declaring a value that will be passed as parameter (for the moment I'm ignoring covariant arrays), for instance if you do this:
int[] array1 = new int[4];
... Then, at the time of passing it as a parameter we'll write it like this:
methodExample(array1)
Also notice that the size of the array must not be passed as parameter, and that by convention the [] part goes right after the type of the array's elements (in fact, int[] is the type of the array), and not after the array's name.
If I understand your question, then you could use Array, and something like
public static void methodExample(Object array1) {
int len = Array.getLength(array1);
for (int i = 0; i < len; i++) {
System.out.printf("array1[%d] = %d%n", i, Array.get(array1, i));
}
}
public static void main(String[] args) {
methodExample(new int[] { 1, 2, 3 });
}
Output is
array1[0] = 1
array1[1] = 2
array1[2] = 3
I assume that you are trying to pass array as a parameter to a method , to initialize it and then call another method to print it?
In java you have to create an object and "allocate" memory space for it by calling to new ...
so you can do like that :
public static void main(String[] args) {
int [] m_array; // creating a array reference
m_array = new int[5]; // allocate "memory" for each of of them or you can consider it as creating a primitive of int in each cell of the array
method(m_array); // passing by value to the method a reference for the array inside the method
}
public void method(int [] arr) // here you are passing a reference by value for the allocated array
{
System.out.println(arr[0]);
}
I am trying to create an array of stacks, in which each stack within the array is of type int.
If I create the array like this: Stack<Integer>[] numbers = new Stack<Integer>[3]; , there is the compile error "Cannot create a generic array of Stack<Integer>". So, I am trying to create the array of Stacks with the wildcard type instead of Integer, and it then does not have this error.
However, if I then try to push an int into one of the stacks (of wildcard "?" type) like this: this.numbers[stackIndex].push(i); , there is the compile error "The method push(capture#1-of ?) in the type Stack<capture#1-of ?> is not applicable for the arguments (int)".
So, how can I properly instantiate an array of Stacks of type int? As of now I am not able to perform push/pop operations on these Stacks...
My reasoning in this is an attempt to program the Tower of Hanoi game. I wanted each of the three rods to be a Stack of type int, each ring to be represented as an int, and the three rods together to be contained as an array of the three Stacks.
Here is some example code:
import java.util.Stack;
public class StackTest {
Stack<?>[] numbers;
public StackTest(int stackLength) {
this.numbers = new Stack<?>[stackLength];
}
public void fillStack(int stackIndex, int numRings) {
for (int i = numRings; i >= 0; i--) {
// this statement has a compile error!
this.numbers[stackIndex].push(i);
}
}
public static void main(String[] args) {
int numberOfRods = 3;
StackTest obj = new StackTest(numberOfRods);
int rodNumber = 0, numberOfRings = 4;
obj.fillStack(rodNumber, numberOfRings);
}
} // end of StackTest
It has to be a raw Stack[] or you can use List<Stack<YourClass>> lstStack = new ArrayList<Stack<YourClass>>().
In this case, I would prefer to use
List<Stack<Integer>> lstStack = new ArrayList<Stack<Integer>>(stackLength);
One solution could be:
public class StackInteger extends Stack<Integer> {
}
And then:
StackInteger[] numbers = new StackInteger[3];
Or even:
Stack<Integer>[] numbers = new StackInteger[3];
My guess is that you should push an Integer rather than an int:
this.numbers[stackIndex].push(Integer.valueOf(i));
I have a class arrayFun with the variable
int[] _array;
I have a method setArray:
public void setArray(int [] array)
{
_array = array;
}
Is my set method implementation correct ?
2).How can I use this method in other class with main ?
I've tried some ridiculous options like:
arrayFun A = new arrayFun(some_constructor_values);
A.setArray(1,2,3,4,5);
That option of course doesn't work...
Try
A.setArray(new int[]{1,2,3,4,5});
Another way to solve this declare the argument as a "varargs" argument as follows:
public void setArray(int ... array) {
_array = array;
}
and then this will work:
A.setArray(1, 2, 3, 4, 5);
You can do the same with a constructor argument.
While I have your attention, it is important that you learn the Java naming conventions, and learn to follow them strictly.
A class name should always start with an uppercase letter
A variable name should always start with a lowercase letter ... unless it is a static final constant.
Using an underscore as a prefix generally frowned on.
For more information, read the Java Style Guidelines.
So your example class should look like this:
public class ArrayFun {
private int[] array;
public void setArray(int ... array) {
this.array = array;
}
}
and should be used like this:
ArrayFun a = new ArrayFun();
a.setArray(1, 2, 3, 4, 5);
You can use this instead
public void setArray(int... array) { _array = array; }
// later
ArrayFun a = new ArrayFun(some_constructor_values);
a.setArray(1,2,3,4,5);
Unless you take a copy of the array, you will be using the same array in the caller and callee.
What you're asking to do doesn't really make sense. Also, why use a function to "set the array", why not just set the array directly:
_array = newArray
You can also set an array's values like this:
int[] array = {1,2,3,4,5};
Your method's signature is :
public void setArray(int[] array)
So it accepts only one argument that is of type array of integers.
But in your method call, you are calling it as:
A.setArray(1,2,3,4,5);
In this you are passing 5 arguments to the method. So it does not match any method with 5 arguments. Thats why it does not work.
You should pass one array of integers.
You can do it in various ways :
int myArr[] = {1,2,3,4,5};
A.setArray(myArr);
or
A.setArray(new int[]new int[]{1,2,3,4,5});
Setting array the way you did is fine. But what you are setting from A.setArray(1,2,3,4,5); will throw you error saying "Method setArray(int,int,int,int,int) is not found".
You can do something like int[] ar = { 1, 2 };
a.setArray(ar);
Suppose I have an int-array and I want to modify it. I know that I cannot assign a new array to array passed as parameter:
public static void main(String[] args)
{
int[] temp_array = {1};
method(temp_array);
System.out.println(temp_array[0]); // prints 1
}
public static void method(int[] n)
{
n = new int[]{2};
}
while I can modify it:
public static void main(String[] args)
{
int[] temp_array = {1};
method(temp_array);
System.out.println(temp_array[0]); // prints 2
}
public static void method(int[] n)
{
n[0] = 2;
}
Then, I tried to assign an arbitrary array to the array passed as parameter using clone():
public static void main(String[] args)
{
int[] temp_array = {1};
method(temp_array);
System.out.println(temp_array[0]); // prints 1 ?!
}
public static void method(int[] n)
{
int[] temp = new int[]{2};
n = temp.clone();
}
Now, I wonder why it prints 1 in last example while I'm just copying the array with clone() which it's just copying the value not the reference. Could you please explain that for me?
EDIT: Is there a way to copy an array to object without changing the reference? I mean to make last example printing 2.
Your examples 1 and 3 are virtually the same in context of the question - you are trying to assign a new value to n (which is a reference to an array passed by value).
The fact that you cloned temp array doesn't matter - all it did was create a copy of temp and then assign it to n.
In order to copy values into array passed into your method method you might want to look at:System.arraycopy
It all, of course, depends on the sizes of your n array and the one you create inside method method.
Assuming they both have the same length, for example, you would do it like that:
public static void main(String[] args)
{
int[] temp_array = {1};
method(temp_array);
System.out.println(temp_array[0]);
}
public static void method(int[] n)
{
int[] temp = new int[]{2};
System.arraycopy(temp, 0, n, 0, n.length);
// or System.arraycopy(temp, 0, n, 0, temp.length) -
// since we assumed that n and temp are of the same length
}
In your method
public static void method(int[] n)
n is another name for the array that way passed in. It points to the same place in memory as the original, which is an array of ints. If you change one of the values stored in that array, all names that point to it will see the change.
However, in the actual method
public static void method(int[] n) {
int[] temp = new int[]{2};
n = temp.clone();
}
You're creating a new array and then saying "the name 'n' now points at this, other array, not the one that was passed in". In effect, the name 'n' is no longer a name for the array that was passed in.
As you correctly note, you cannot assign to the array reference passed as a parameter. (Or more precisely, the assignment won't have any effect in the caller.)
This is about the best that you can do:
public static void method(int[] n) {
int[] temp = new int[]{2};
for (int i = 0; i < temp.length; i++) {
n[i] = temp[i];
}
// ... or the equivalent using System.arraycopy(...) or some such
}
Of course, this only works properly if the size of the input array is the same as the size of the array you are copying to it. (How you should deal with this will be application specific ...)
For the record Java passes the array reference by value. It doesn't pass the array contents by value. And clone won't help to solve this problem. (At least, not with the method signature as declared.)
In your method method, nothing that you assign to n will ever change the value of the object passed in and assigned to n. At the beginning of method, n points to an array. When you assign n to equal another array, you've simply re-pointed which array n points to, and haven't changed anything about temp_array from the main method.