Saving the output of array permutations into a 2D array - java

I am trying to save the permutation result of an array into a 2d array. let's say I have an array {1,2,3,4}, I created a 2D array with rows: N! and columns 4. Is it possible to save all the results into 2D array. For example I have the following output I want to save it into 2D array
[1, 2, 3, 4]
[1, 2, 4, 3]

Your question is unclear. Just in case you are wondering how to create and populate a "2D array" here's what I can tell :
import java.util.Arrays;
public class ArraysOfArrays {
public static void main(String[] args) {
// This is your '1D' array
int[] init = {1, 2, 3, 4};
//This is you '2D' array, 24 possibilities of 4 items in order
int[][] combinations = new int[24][4];
// fill your 2D array with the combinations you compute like that :
combinations[0] = new int[] {1,2,3,4};
combinations[1] = new int[] {1,2,4,3};
combinations[2] = new int[] {1,3,2,4};
combinations[3] = new int[] {1,3,4,2};
combinations[4] = new int[] {1,4,2,3};
combinations[5] = new int[] {1,4,3,2};
//...
combinations[23] = new int[] {4,3,2,1};
// or you can assign the individual values one by one :
combinations[0][0] = 1;
combinations[0][1] = 2;
combinations[0][2] = 3;
combinations[0][3] = 4;
System.out.println(Arrays.toString(combinations[3]));
}
}
Hope that helps!

If you want to store many arrays in a "2D" array, then use a loop as follows:
int size = 24; //this should be n! for permutations of n values.
combs[][] = new int[size][];
for (int i = 0; i < size; i++) {
combs[i] = getNextPermutationArray();
}
And Java does not have true multidimensional arrays. It simply has arrays of arrays of arrays, etc.

Related

Is there any way to declare size more than the number of elements present in the array in a single line [duplicate]

I am initializing an array like this:
public class Array {
int data[] = new int[10];
/** Creates a new instance of Array */
public Array() {
data[10] = {10,20,30,40,50,60,71,80,90,91};
}
}
NetBeans points to an error at this line:
data[10] = {10,20,30,40,50,60,71,80,90,91};
How can I solve the problem?
data[10] = {10,20,30,40,50,60,71,80,90,91};
The above is not correct (syntax error). It means you are assigning an array to data[10] which can hold just an element.
If you want to initialize an array, try using Array Initializer:
int[] data = {10,20,30,40,50,60,71,80,90,91};
// or
int[] data;
data = new int[] {10,20,30,40,50,60,71,80,90,91};
Notice the difference between the two declarations. When assigning a new array to a declared variable, new must be used.
Even if you correct the syntax, accessing data[10] is still incorrect (You can only access data[0] to data[9] because index of arrays in Java is 0-based). Accessing data[10] will throw an ArrayIndexOutOfBoundsException.
Try
data = new int[] {10,20,30,40,50,60,71,80,90,91 };
When you create an array of size 10 it allocated 10 slots but from 0 to 9.
This for loop might help you see that a little better.
public class Array {
int[] data = new int[10];
/** Creates a new instance of an int Array */
public Array() {
for(int i = 0; i < data.length; i++) {
data[i] = i*10;
}
}
}
You can do:
int[] data = {10,20,30,40,50,60,71,80,90,91};
Syntax
Datatype[] variable = new Datatype[] { value1,value2.... }
Datatype variable[] = new Datatype[] { value1,value2.... }
Example :
int [] points = new int[]{ 1,2,3,4 };
Rather than learning un-Official websites learn from oracle website
link follows:Click here
*You can find Initialization as well as declaration with full description *
int n; // size of array here 10
int[] a = new int[n];
for (int i = 0; i < a.length; i++)
{
a[i] = Integer.parseInt(s.nextLine()); // using Scanner class
}
Input:
10//array size
10
20
30
40
50
60
71
80
90
91
Displaying data:
for (int i = 0; i < a.length; i++)
{
System.out.println(a[i] + " ");
}
Output:
10 20 30 40 50 60 71 80 90 91
You cannot initialize an array like that. In addition to what others have suggested, you can do :
data[0] = 10;
data[1] = 20;
...
data[9] = 91;
If you want to initialize an array in a constructor,
you can't use those array initializer like.
data= {10,20,30,40,50,60,71,80,90,91};
Just change it to
data = new int[] {10,20,30,40,50,60,71,80,90,91};
You don't have to specify the size with data[10] = new int[] { 10,...,91}
Just declare the property / field with int[] data; and initialize it like above.
The corrected version of your code would look like the following:
public class Array {
int[] data;
public Array() {
data = new int[] {10,20,30,40,50,60,71,80,90,91};
}
}
As you see the bracket are empty. There isn't any need to tell the size between the brackets, because the initialization and its size are specified by the count of the elements between the curly brackets.
you are trying to set the 10th element of the array to the array try
data = new int[] {10,20,30,40,50,60,71,80,90,91};
FTFY
Maybe this will work:
public class Array {
int data[] = new int[10];
/* Creates a new instance of Array */
public Array() {
data= {10,20,30,40,50,60,71,80,90,91};
}
}
int myArray2[] = new int[3];
int[] myArray = new int[3];
int[] intArray = {13, 14, 15};
int[] intArray = new int[]{7, 8, 9};
int[] intArray = IntStream.range(1, 11).toArray();
int[] intArray = IntStream.rangeClosed(1, 10).toArray();
int[] intArray = IntStream.of(6, 2, 4, 5, 7).toArray();
int[] intArray = IntStream.of(6, 2, 4, 5, 7).sorted().toArray();

Common elements between two randomly formed java arrays

Frame of the question:
Write a class called CommonElements with a single method main that will:
Create and obtain two integer arrays (arrayA and arrayB) using RandomIntegerArrayCreator type objects and its methods,
find the number of common elements between arrayA and arrayB (say: if integer 2 appears in arrayA once and twice in arrayB, that counts as ONE common element between the two),
Constraints / notes:
All array elements are integers from the the set {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} and can appear multiple times in each array,
Arrays A and B do NOT have to be of the same size,
Arrays A and B CAN be empty (no elements),
Arrays A and B will NOT be sorted.
The code that I have already created:
import java.util.Random;
public class RandomIntegerArrayCreator {
int[] arr;
RandomIntegerArrayCreator(){
Random rand = new Random();
int size = rand.nextInt(16);
arr = new int[size];
for(int i=0;i<size;i++){
arr[i] = rand.nextInt(11);
}
}
public int getArraySize(){
return this.arr.length;
}
public int[] getArray(){
return this.arr;
}
public static void main(String[] args) {
RandomIntegerArrayCreator r = new RandomIntegerArrayCreator();
System.out.println("Size = "+r.getArraySize());
int[] arr = r.getArray();
System.out.print("Generated array is ");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
}
Here's the pseudo code for what you're looking for.
for i=0, i<size arrayA
for j=0, j<size arrayB
if arrayA[i] == arrayB[j]
if(arrayA is not in dummyarray)
dummyarray.append(arrayA[i])
counter++
Edit: Basically, you iterate through arrayA and go through each element in arrayB and check if there's something that matches (For instance, arrayA[3] = 4 and arrayB[2] = 4, then there's a match). You add the number to a dummy list which you can check later to see if there's been a duplicate match.

How to set the dimensions of a multi-dimensional array? [duplicate]

Suppose we have the Java code:
Object arr = Array.newInstance(Array.class, 5);
Would that run? As a further note, what if we were to try something like this:
Object arr1 = Array.newInstance(Array.class, 2);
Object arr2 = Array.newInstance(String.class, 4);
Object arr3 = Array.newInstance(String.class, 4);
Array.set(arr1, 0, arr2);
Array.set(arr1, 1, arr3);
Would arr1 then be a 2D array equivalent to:
String[2][4] arr1;
How about this: what if we don't know the dimensions of this array until runtime?
Edit: if this helps (I'm sure it would...) we're trying to parse an array of unknown dimensions from a String of the form
[value1, value2, ...]
or
[ [value11, value12, ...] [value21, value22, ...] ...]
And so on
Edit2: In case someone as stupid as I am tries this junk, here's a version that at least compiles and runs. Whether or not the logic is sound is another question entirely...
Object arr1 = Array.newInstance(Object.class, x);
Object arr11 = Array.newInstance(Object.class, y);
Object arr12 = Array.newInstance(Object.class, y);
...
Object arr1x = Array.newInstance(Object.class, y);
Array.set(arr1, 0, arr11);
Array.set(arr1, 1, arr12);
...
Array.set(arr1, x-1, arr1x);
And so on. It just has to be a giant nested array of Objects
It is actually possible to do in java. (I'm a bit surprised I must say.)
Disclaimer; I never ever want to see this code anywhere else than as an answer to this question. I strongly encourage you to use Lists.
import java.lang.reflect.Array;
import java.util.*;
public class Test {
public static int[] tail(int[] arr) {
return Arrays.copyOfRange(arr, 1, arr.length);
}
public static void setValue(Object array, String value, int... indecies) {
if (indecies.length == 1)
((String[]) array)[indecies[0]] = value;
else
setValue(Array.get(array, indecies[0]), value, tail(indecies));
}
public static void fillWithSomeValues(Object array, String v, int... sizes) {
for (int i = 0; i < sizes[0]; i++)
if (sizes.length == 1)
((String[]) array)[i] = v + i;
else
fillWithSomeValues(Array.get(array, i), v + i, tail(sizes));
}
public static void main(String[] args) {
// Randomly choose number of dimensions (1, 2 or 3) at runtime.
Random r = new Random();
int dims = 1 + r.nextInt(3);
// Randomly choose array lengths (1, 2 or 3) at runtime.
int[] sizes = new int[dims];
for (int i = 0; i < sizes.length; i++)
sizes[i] = 1 + r.nextInt(3);
// Create array
System.out.println("Creating array with dimensions / sizes: " +
Arrays.toString(sizes).replaceAll(", ", "]["));
Object multiDimArray = Array.newInstance(String.class, sizes);
// Fill with some
fillWithSomeValues(multiDimArray, "pos ", sizes);
System.out.println(Arrays.deepToString((Object[]) multiDimArray));
}
}
Example Output:
Creating array with dimensions / sizes: [2][3][2]
[[[pos 000, pos 001], [pos 010, pos 011], [pos 020, pos 021]],
[[pos 100, pos 101], [pos 110, pos 111], [pos 120, pos 121]]]
Arrays are type-safe in java - that applies to simple arrays and "multi-dimensional" arrays - i.e. arrays of arrays.
If the depth of nesting is variable at runtime, then the best you can do is to use an array that corresponds to the known minimum nesting depth (presumably 1.) The elements in this array with then either be simple elements, or if further nesting is required, another array. An Object[] array will allow you to do this, since nested arrays themselves are also considered Objects, and so fit within the type system.
If the nesting is completely regular, then you can preempt this regularity and create an appropriate multimensional array, using Array.newInstance(String.class, dimension1, dimension2, ...), If nesting is irregular, you will be better off using nested lists, which allow for a "jagged" structure and dynamic sizing. You can have a jagged structure, at the expence of generics. Generics cannot be used if the structure is jagged since some elements may be simple items while other elements may be further nested lists.
So you can pass multiple dimensions to Array.newInstance, but that forces a fixed length for each dimension. If that's OK, you can use this:
// We already know from scanning the input that we need a 2 x 4 array.
// Obviously this array would be created some other way. Probably through
// a List.toArray operation.
final int[] dimensions = new int[2];
dimensions[0] = 2;
dimensions[1] = 4;
// Create the array, giving the dimensions as the second input.
Object array = Array.newInstance(String.class, dimensions);
// At this point, array is a String[2][4].
// It looks like this, when the first dimension is output:
// [[Ljava.lang.String;#3e25a5, [Ljava.lang.String;#19821f]
//
// The second dimensions look like this:
// [null, null, null, null]
The other option would be to build them up from the bottom, using getClass on the previous level of array as the input for the next level. The following code runs and produces a jagged array as defined by the nodes:
import java.lang.reflect.Array;
public class DynamicArrayTest
{
private static class Node
{
public java.util.List<Node> children = new java.util.LinkedList<Node>();
public int length = 0;
}
public static void main(String[] args)
{
Node node1 = new Node();
node1.length = 1;
Node node2 = new Node();
node2.length = 2;
Node node3 = new Node();
node3.length = 3;
Node node4 = new Node();
node4.children.add(node1);
node4.children.add(node2);
Node node5 = new Node();
node5.children.add(node3);
Node node6 = new Node();
node6.children.add(node4);
node6.children.add(node5);
Object array = createArray(String.class, node6);
outputArray(array); System.out.println();
}
private static Object createArray(Class<?> type, Node root)
{
if (root.length != 0)
{
return Array.newInstance(type, root.length);
}
else
{
java.util.List<Object> children = new java.util.ArrayList<Object>(root.children.size());
for(Node child : root.children)
{
children.add(createArray(type, child));
}
Object array = Array.newInstance(children.get(0).getClass(), children.size());
for(int i = 0; i < Array.getLength(array); ++i)
{
Array.set(array, i, children.get(i));
}
return array;
}
}
private static void outputArray(Object array)
{
System.out.print("[ ");
for(int i = 0; i < Array.getLength(array); ++i)
{
Object element = Array.get(array, i);
if (element != null && element.getClass().isArray())
outputArray(element);
else
System.out.print(element);
System.out.print(", ");
}
System.out.print("]");
}
}
As a further note, what if we were to try something like this:
Object arr1 = Array.newInstance(Array.class, 2);
Object arr2 = Array.newInstance(String.class, 4);
Object arr3 = Array.newInstance(String.class, 4);
Array.set(arr1, 0, arr2);
...
No, you can't set an String[] value like that. You run into
Exception in thread "main" java.lang.IllegalArgumentException: array element type mismatch
at java.lang.reflect.Array.set(Native Method)
at Test.main(Test.java:12)
Ok, if you are unsure of the dimensions of the array, then the following method won't work. However, if you do know the dimensions, do not use reflection. Do the following:
You can dynamically build 2d arrays much easier than that.
int x = //some value
int y = //some other value
String[][] arr = new String[x][y];
This will 'dynamically' create an x by y 2d array.
So I came across this question with code to extract coefficients from a polynomial with variable numbers of variables. So a user might
want the coefficient array for a polynomial in two variables 3 x^2 + 2 x y or it could be one with three variables. Ideally, you want a multiple dimension array which the user can easily interrogate so can be cast to
Integer[], Integer[][] etc.
This basically uses the same technique as jdmichal's answer, using the Array.newInstance(obj.getClass(), size) method. For a multi dimensional arrays obj can be an array of one less dimension.
Sample code with randomly created elements
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Random;
public class MultiDimArray {
static Random rand = new Random();
/**
* Create an multi-dimensional array
* #param depth number of dimensions
* #return
*/
static Object buildArray(int depth) {
if(depth ==1) { // For 1D case just use a normal array
int size = rand.nextInt(3)+1;
Integer[] res = new Integer[size];
for(int i=0;i<size;++i) {
res[i] = new Integer(i);
}
return res;
}
// 2 or more dimensions, using recursion
int size = rand.nextInt(3)+1;
// Need to get first items so can find its class
Object ele0 = buildArray(depth-1);
// create array of correct type
Object res = Array.newInstance(ele0.getClass(), size);
Array.set(res, 0, ele0);
for(int i=1;i<size;++i) {
Array.set(res, i, buildArray(depth-1));
}
return res;
}
public static void main(String[] args) {
Integer[] oneD = (Integer[]) buildArray(1);
System.out.println(Arrays.deepToString(oneD));
Integer[][] twoD = (Integer[][]) buildArray(2);
System.out.println(Arrays.deepToString(twoD));
Integer[][][] threeD = (Integer[][][]) buildArray(3);
System.out.println(Arrays.deepToString(threeD));
}
}
Effective Java item # (I don't remember ) : Know and use the libraries.
You can use a List and use the toArray method:
List<String[]> twoDimension = new ArrayList<String[]>();
To convert it to an array you would use:
String [][] theArray = twoDimension.toArray( new String[twoDimension.size()][] );
The trick is, the outer array is declared to hold String[] ( string arrays ) which in turn can be dynamically created with another List<String> or, if your're parsing strings with the String.split method.
Demo
Focusing on the dynamic creation of the array and not in the parsing, here's an example on how does it works used in conjunction with String.split
// and array which contains N elements of M size
String input = "[[1],[2,3],[4,5,6,7],[8,9,10,11,12,13]]";
// Declare your dynamic array
List<String[]> multiDimArray = new ArrayList<String[]>();
// split where ],[ is found, just ignore the leading [[ and the trailing ]]
String [] parts = input.replaceAll("\\[\\[|\\]\\]","")
.split("\\],\\[");
// now split by comma and add it to the list
for( String s : parts ){
multiDimArray.add( s.split(",") ) ;
}
String [][] result = multiDimArray.toArray( new String[multiDimArray.size()][]);
There. Now your result is a two dimensional dynamically created array containing : [[1], [2, 3], [4, 5, 6, 7], [8, 9, 10, 11, 12, 13]] as expected.
Here's a complete running demo, which also adds more regexp to the mix, to eliminate white spaces.
I let you handle the other scenarios.

Need help creating a method that returns an array whose elements are squares of another array

I have an assignment that requires me to create a method that takes an array of double named dArray as parameter and returns another array whose elements are squares of the elements of dArray.
For example,
if dArray is {1, 4, 6, 7}, the the returned array will be {1, 16, 36, 49}.
Any help would be greatly appreciated!
Here is what I have written so far, but it doesn't work right.
public static double[] squareArray(double[] dArray) {
double[] squareArray = new double[10];
for(int i = 0; i < dArray.length ; i++) {
dArray[] = dArray * dArray;
}
return squareArray;
}
class Test {
public static void main(String [ ] args) {
double[] scores = {3, 9, 3, 3};
double[] scoresSquared = squareArray(scores);
for (int i =0; i <scoresSquared.length; i++) {
System.out.println(scoresSquared[i] + " ");
}
}
public static double[] squareArray(double[] dArray){
double[] squareArray = new double[dArray.length];
for (int i = 0; i < dArray.length ; i++){
squareArray[i]= dArray[i] * dArray[i];
}
return squareArray;
}
}
It would appear that you are squaring the array more than you need to. If every element in the array needs to be squared, you should only have to loop over that array once, but in your code you have two loops.
That's part of the issue.
Another is that you're trying to multiply arrays, which isn't allowed. Inside that method, you need to loop over the array and square each element in it.
Try this:
In your squareArray(), create a List< Double> or something like that.
Iterate through each double in the double[] and add that double squared to the List.
Return (listname).toArray();
You're almost there.
Copy the contents of the array you're receiving and place them into your internal squareArray.
Iterate over squareArray and apply your algorithm (to access specific indexes while in the loop, use squareArray[i])
Return squareArray.

Is it possible to dynamically build a multi-dimensional array in Java?

Suppose we have the Java code:
Object arr = Array.newInstance(Array.class, 5);
Would that run? As a further note, what if we were to try something like this:
Object arr1 = Array.newInstance(Array.class, 2);
Object arr2 = Array.newInstance(String.class, 4);
Object arr3 = Array.newInstance(String.class, 4);
Array.set(arr1, 0, arr2);
Array.set(arr1, 1, arr3);
Would arr1 then be a 2D array equivalent to:
String[2][4] arr1;
How about this: what if we don't know the dimensions of this array until runtime?
Edit: if this helps (I'm sure it would...) we're trying to parse an array of unknown dimensions from a String of the form
[value1, value2, ...]
or
[ [value11, value12, ...] [value21, value22, ...] ...]
And so on
Edit2: In case someone as stupid as I am tries this junk, here's a version that at least compiles and runs. Whether or not the logic is sound is another question entirely...
Object arr1 = Array.newInstance(Object.class, x);
Object arr11 = Array.newInstance(Object.class, y);
Object arr12 = Array.newInstance(Object.class, y);
...
Object arr1x = Array.newInstance(Object.class, y);
Array.set(arr1, 0, arr11);
Array.set(arr1, 1, arr12);
...
Array.set(arr1, x-1, arr1x);
And so on. It just has to be a giant nested array of Objects
It is actually possible to do in java. (I'm a bit surprised I must say.)
Disclaimer; I never ever want to see this code anywhere else than as an answer to this question. I strongly encourage you to use Lists.
import java.lang.reflect.Array;
import java.util.*;
public class Test {
public static int[] tail(int[] arr) {
return Arrays.copyOfRange(arr, 1, arr.length);
}
public static void setValue(Object array, String value, int... indecies) {
if (indecies.length == 1)
((String[]) array)[indecies[0]] = value;
else
setValue(Array.get(array, indecies[0]), value, tail(indecies));
}
public static void fillWithSomeValues(Object array, String v, int... sizes) {
for (int i = 0; i < sizes[0]; i++)
if (sizes.length == 1)
((String[]) array)[i] = v + i;
else
fillWithSomeValues(Array.get(array, i), v + i, tail(sizes));
}
public static void main(String[] args) {
// Randomly choose number of dimensions (1, 2 or 3) at runtime.
Random r = new Random();
int dims = 1 + r.nextInt(3);
// Randomly choose array lengths (1, 2 or 3) at runtime.
int[] sizes = new int[dims];
for (int i = 0; i < sizes.length; i++)
sizes[i] = 1 + r.nextInt(3);
// Create array
System.out.println("Creating array with dimensions / sizes: " +
Arrays.toString(sizes).replaceAll(", ", "]["));
Object multiDimArray = Array.newInstance(String.class, sizes);
// Fill with some
fillWithSomeValues(multiDimArray, "pos ", sizes);
System.out.println(Arrays.deepToString((Object[]) multiDimArray));
}
}
Example Output:
Creating array with dimensions / sizes: [2][3][2]
[[[pos 000, pos 001], [pos 010, pos 011], [pos 020, pos 021]],
[[pos 100, pos 101], [pos 110, pos 111], [pos 120, pos 121]]]
Arrays are type-safe in java - that applies to simple arrays and "multi-dimensional" arrays - i.e. arrays of arrays.
If the depth of nesting is variable at runtime, then the best you can do is to use an array that corresponds to the known minimum nesting depth (presumably 1.) The elements in this array with then either be simple elements, or if further nesting is required, another array. An Object[] array will allow you to do this, since nested arrays themselves are also considered Objects, and so fit within the type system.
If the nesting is completely regular, then you can preempt this regularity and create an appropriate multimensional array, using Array.newInstance(String.class, dimension1, dimension2, ...), If nesting is irregular, you will be better off using nested lists, which allow for a "jagged" structure and dynamic sizing. You can have a jagged structure, at the expence of generics. Generics cannot be used if the structure is jagged since some elements may be simple items while other elements may be further nested lists.
So you can pass multiple dimensions to Array.newInstance, but that forces a fixed length for each dimension. If that's OK, you can use this:
// We already know from scanning the input that we need a 2 x 4 array.
// Obviously this array would be created some other way. Probably through
// a List.toArray operation.
final int[] dimensions = new int[2];
dimensions[0] = 2;
dimensions[1] = 4;
// Create the array, giving the dimensions as the second input.
Object array = Array.newInstance(String.class, dimensions);
// At this point, array is a String[2][4].
// It looks like this, when the first dimension is output:
// [[Ljava.lang.String;#3e25a5, [Ljava.lang.String;#19821f]
//
// The second dimensions look like this:
// [null, null, null, null]
The other option would be to build them up from the bottom, using getClass on the previous level of array as the input for the next level. The following code runs and produces a jagged array as defined by the nodes:
import java.lang.reflect.Array;
public class DynamicArrayTest
{
private static class Node
{
public java.util.List<Node> children = new java.util.LinkedList<Node>();
public int length = 0;
}
public static void main(String[] args)
{
Node node1 = new Node();
node1.length = 1;
Node node2 = new Node();
node2.length = 2;
Node node3 = new Node();
node3.length = 3;
Node node4 = new Node();
node4.children.add(node1);
node4.children.add(node2);
Node node5 = new Node();
node5.children.add(node3);
Node node6 = new Node();
node6.children.add(node4);
node6.children.add(node5);
Object array = createArray(String.class, node6);
outputArray(array); System.out.println();
}
private static Object createArray(Class<?> type, Node root)
{
if (root.length != 0)
{
return Array.newInstance(type, root.length);
}
else
{
java.util.List<Object> children = new java.util.ArrayList<Object>(root.children.size());
for(Node child : root.children)
{
children.add(createArray(type, child));
}
Object array = Array.newInstance(children.get(0).getClass(), children.size());
for(int i = 0; i < Array.getLength(array); ++i)
{
Array.set(array, i, children.get(i));
}
return array;
}
}
private static void outputArray(Object array)
{
System.out.print("[ ");
for(int i = 0; i < Array.getLength(array); ++i)
{
Object element = Array.get(array, i);
if (element != null && element.getClass().isArray())
outputArray(element);
else
System.out.print(element);
System.out.print(", ");
}
System.out.print("]");
}
}
As a further note, what if we were to try something like this:
Object arr1 = Array.newInstance(Array.class, 2);
Object arr2 = Array.newInstance(String.class, 4);
Object arr3 = Array.newInstance(String.class, 4);
Array.set(arr1, 0, arr2);
...
No, you can't set an String[] value like that. You run into
Exception in thread "main" java.lang.IllegalArgumentException: array element type mismatch
at java.lang.reflect.Array.set(Native Method)
at Test.main(Test.java:12)
Ok, if you are unsure of the dimensions of the array, then the following method won't work. However, if you do know the dimensions, do not use reflection. Do the following:
You can dynamically build 2d arrays much easier than that.
int x = //some value
int y = //some other value
String[][] arr = new String[x][y];
This will 'dynamically' create an x by y 2d array.
So I came across this question with code to extract coefficients from a polynomial with variable numbers of variables. So a user might
want the coefficient array for a polynomial in two variables 3 x^2 + 2 x y or it could be one with three variables. Ideally, you want a multiple dimension array which the user can easily interrogate so can be cast to
Integer[], Integer[][] etc.
This basically uses the same technique as jdmichal's answer, using the Array.newInstance(obj.getClass(), size) method. For a multi dimensional arrays obj can be an array of one less dimension.
Sample code with randomly created elements
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Random;
public class MultiDimArray {
static Random rand = new Random();
/**
* Create an multi-dimensional array
* #param depth number of dimensions
* #return
*/
static Object buildArray(int depth) {
if(depth ==1) { // For 1D case just use a normal array
int size = rand.nextInt(3)+1;
Integer[] res = new Integer[size];
for(int i=0;i<size;++i) {
res[i] = new Integer(i);
}
return res;
}
// 2 or more dimensions, using recursion
int size = rand.nextInt(3)+1;
// Need to get first items so can find its class
Object ele0 = buildArray(depth-1);
// create array of correct type
Object res = Array.newInstance(ele0.getClass(), size);
Array.set(res, 0, ele0);
for(int i=1;i<size;++i) {
Array.set(res, i, buildArray(depth-1));
}
return res;
}
public static void main(String[] args) {
Integer[] oneD = (Integer[]) buildArray(1);
System.out.println(Arrays.deepToString(oneD));
Integer[][] twoD = (Integer[][]) buildArray(2);
System.out.println(Arrays.deepToString(twoD));
Integer[][][] threeD = (Integer[][][]) buildArray(3);
System.out.println(Arrays.deepToString(threeD));
}
}
Effective Java item # (I don't remember ) : Know and use the libraries.
You can use a List and use the toArray method:
List<String[]> twoDimension = new ArrayList<String[]>();
To convert it to an array you would use:
String [][] theArray = twoDimension.toArray( new String[twoDimension.size()][] );
The trick is, the outer array is declared to hold String[] ( string arrays ) which in turn can be dynamically created with another List<String> or, if your're parsing strings with the String.split method.
Demo
Focusing on the dynamic creation of the array and not in the parsing, here's an example on how does it works used in conjunction with String.split
// and array which contains N elements of M size
String input = "[[1],[2,3],[4,5,6,7],[8,9,10,11,12,13]]";
// Declare your dynamic array
List<String[]> multiDimArray = new ArrayList<String[]>();
// split where ],[ is found, just ignore the leading [[ and the trailing ]]
String [] parts = input.replaceAll("\\[\\[|\\]\\]","")
.split("\\],\\[");
// now split by comma and add it to the list
for( String s : parts ){
multiDimArray.add( s.split(",") ) ;
}
String [][] result = multiDimArray.toArray( new String[multiDimArray.size()][]);
There. Now your result is a two dimensional dynamically created array containing : [[1], [2, 3], [4, 5, 6, 7], [8, 9, 10, 11, 12, 13]] as expected.
Here's a complete running demo, which also adds more regexp to the mix, to eliminate white spaces.
I let you handle the other scenarios.

Categories