How to convert List of int array to 2D Array? - java

Given a list of int[] [{7, 0}, {7, 1}, {6, 1}, {5, 0}, {5, 2}, {4, 4}] I need to convert it into 2D Array {{7, 0}, {7, 1}, {6, 1}, {5, 0}, {5, 2}, {4, 4}} using Java 8.
Before Java 8 we could use the following logic: temp is List<int[]> which contains above list of elements. First res[][] is created of the same size as a List of elements in temp.
int[][] res = new int[temp.size()][2];
for (int i = 0; i < temp.size(); i++) {
res[i][0] = temp.get(i)[0];
res[i][1] = temp.get(i)[1];
}

Try this.
List<int[]> list = List.of(
new int[] {7, 0}, new int[] {7, 1},
new int[] {6, 1}, new int[] {5, 0},
new int[] {5, 2}, new int[] {4, 4});
int[][] res = list.stream().toArray(int[][]::new);
System.out.println(Arrays.deepToString(res));
result
[[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]
See this code run live at IdeOne.com.

Related

Flatmapping a 2D array by column rather than row in Java

Given the following two dimensional array
int[][] arr = {{1, 2}, {3, 4}, {5, 6}};
How can I flatten it column-by-column using the Java 8 Stream API? I want to get:
int[] result = {1, 3, 5, 2, 4, 6};
I tried doing a simple flatMap, but this flattens row-by-row and results in the wrong order:
// result is { 1, 2, 3, 4, 5, 6 }
int[] result = Arrays.stream(arr)
.flatMapToInt(Arrays::stream)
.toArray();
I considered transposing the array first so that I can use the above snippet, but creating an intermediate, transposed copy of the array seems unnecessary. How can I flatmap by column directly?
It can be assumed that all the nested arrays are of same length.
You can stream the inner indexes and flatMap to each outer array:
IntStream.range(0, arr[0].length)
.flatMap(i -> Arrays.stream(arr).mapToInt(a -> a[i]))
.toArray()
If we assume that all the nested arrays are of the same length we can use nested loops:
int[][] arr = {{1, 2}, {3, 4}, {5, 6}};
int[] res = new int[arr.length * arr[0].length];
int j = 0;
for (int i = 0; i < arr[0].length; i++) {
for (int[] a : arr) {
res[j++] = a[i];
}
}
System.out.println(Arrays.toString(res)); // [1, 3, 5, 2, 4, 6]
This is another way to do it:
int[][] nestedArray = {{1, 12, 2}, {1, 13, 11, 5, 16}, {7, 8, 9}};
LinkedList<Integer> theList = new LinkedList<>();
for(int[] sList: nestedArray) {
stream(sList)
.forEach(theList::add);
}
theList.stream()
.forEach(e ->System.out.println(e));
I revised the previous code to more KISS and readable.
int[][] nestedArray = {{3, 4, 5, 6}, {1, 2}, {7, 8, 9}};
LinkedList<Integer> theList = new LinkedList<>();
for(int[] sList: nestedArray) {
stream(sList)
.forEach(theList::add);
}
theList.stream()
.forEach(e ->System.out.println(e));

How to get all the diagonals from a matrix (2d array) in java efficiently

I need an efficient way of getting all the diagonals from a matrix in java, for example given the following matrix:
System.out.println(Double.POSITIVE_INFINITY-1);
int[][] mat = { {1 , 2 , 3},
{6 , 7 , 8},
{11, 12, 13}};
ArrayList<ArrayList<Integer>> diagonals = new ArrayList<>();
The array list diagonals should contain:
[[11], [6, 12], [1, 7, 13], [2, 8], [3], [1], [6, 2], [11, 7, 3], [12, 8], [13]]

Java Method that checks to see if an array is a Latin Square

I am creating a program with a method whose input is an 2D array of int, that checks to see if arrays are Latin Squares.
For example a Latin Square would look like this:
1 2 3
2 3 1
3 1 2
This is my code so far:
public class LatinSquare {
public boolean isLatinSquare(int[][] a){
int[] row= new int[a.length];
int[] column = new int[a[0].length];
for (int j = 0; j<column.length; j++){
for (int i = 0; i<row.length;i++){
row[i] = a[i][j];
}
for (int i = 0; i<row.length -1; i++){
for (int x= i+1; x<=row.length;x++){
if (row[i]==row[x])
return false;
}
}
}
}
The code is not fully complete but I just wanted to know if someone could answer some questions before I head in the wrong direction if I am doing something wrong.
My Question: Is this the best approach for checking arrays to see if they would fulfill a Latin Square? My thought process is that I start at column '0' and then go through the row comparing each number to each other making sure they are not equal, and move through each column this way. Is this the wrong way to be approaching this?
Lots of nested loops will degrade performance. Here is a faster version, but it uses a bit more memory.
It relies on the values of the square being in the range 1 to N, where N is the square size.
private static boolean isLatinSquare(int[][] square) {
boolean[][] foundInRow = new boolean[square.length][square.length];
boolean[][] foundInCol = new boolean[square.length][square.length];
for (int row = 0; row < square.length; row++) {
if (square[row].length != square.length)
return false; // Not a square
for (int col = 0; col < square.length; col++) {
int idx = square[row][col] - 1;
if (foundInRow[row][idx] || foundInCol[col][idx])
return false;
foundInRow[row][idx] = foundInCol[col][idx] = true;
}
}
return true;
}
Test
System.out.println(isLatinSquare(new int[][] { {1, 2, 3},
{2, 3, 1},
{3, 1, 2} }));
System.out.println(isLatinSquare(new int[][] { {1, 2, 3},
{3, 1, 2},
{2, 3, 1} }));
System.out.println(isLatinSquare(new int[][] { {1, 3, 2},
{2, 1, 3},
{3, 2, 1} }));
System.out.println(isLatinSquare(new int[][] { {1, 3, 2},
{3, 2, 1},
{2, 1, 3} }));
System.out.println(isLatinSquare(new int[][] { {1, 3, 2},
{3, 2, 1},
{1, 3, 2} }));
System.out.println(isLatinSquare(new int[][] { {1, 3, 1},
{3, 2, 3},
{2, 1, 2} }));
System.out.println(isLatinSquare(new int[][] { {1, 2, 3},
{2, 3},
{3, 1, 2} }));
Output
true
true
true
true
false
false
false

Double Array: Out of Bounds

I am trying to write a code that finds the average of the inputs of a 2D array:
This is what I have written:
public class AverageLength
{
public static void main(String[] args)
{
int sum = 0;
int w = 0;
int[][] foobar = new int[][]
{
{0, 5, 7},
{3, 2, 4},
{8, 7, 3},
{1, 5, 3}
};
for (int i = 0; i < foobar.length; i++)
{
for (int j = 0; j <foobar[0].length; j++)
{
System.out.println(foobar[i][j]);
sum = sum + foobar[i][j];
w++;
}
} System.out.println("Average = " + sum/w);
}
}
However, if I change the array lengths and try what follows:
int[][] foobar = new int[][]
{
{0, 5, 7, 3},
{3, 3, 5, 7, 8, 4},
{8, 3},
{1, 5, 1, 2, 3}
};
it gives me the following error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at AverageLength.main(AverageLength.java:18)
How can I fix this issue?
change
foobar[0].length
to
foobar[i].length
when your sub arrays lengths are different you should get corresponding length
for example
{0, 5, 7, 3},
{3, 3, 5, 7, 8, 4},
{8, 3},
in this case
foobar[0].length is 4 .so when you loop through 3rd sub array {8, 3}
and when you try to access 2nd index [3rd element ] you get error
ArrayIndexOutOfBoundsException: 2
because there is no 2nd index.
and also in 2nd sub array {3, 3, 5, 7, 8, 4}, value 8 and 4 will not print because you loop 4 times .
When you check in your seccond for for array length you should use i not 0, because if you use 0 you will always get length of just first array.
for (int j = 0; j <foobar[i].length; j++)
By using foobar[0].length you are using the length of the first inner array for every inner array. Use foobar[i].length instead, which will calculate the current array's length.
By the way: Calculating averages of int arrays can be done java-internally since Java8. An example of how to use Java8's streaming API to solve this task:
import java.util.Arrays;
public class AverageLength
{
public static void main(String[] args)
{
int[][] foobar = new int[][]
{
{0, 5, 7},
{3, 2, 4},
{8, 7, 3},
{1, 5, 3}
};
System.out.print("Average = ");
System.out.println(
// convert 2D array to stream of arrays
Arrays.stream(foobar)
// flatten 2D array to 1D array
.flatMapToInt(Arrays::stream)
// let java calculate the average
.average()
// get result
.getAsDouble());
}
}
Benefits:
code is easier to understand
your program is potentially much faster
code can be easily changed to run in several threads (use .parallel())

Rearrange array. Make 1, 3, 5 to 3, 5, 1 and etc

Let's say I have an array:
int array[][] = {{1, 2, 3}, {2, 5, 7}, {4, 2, 1}};
How can I randomly make it
int array[][] = {{2, 5, 7}, {1, 2, 3}, {4, 2, 1}};
or
int array[][] = {{4, 2, 1}, {2, 5, 7}, {1, 2, 3},};
And so on.
Is there any JAVA function to help me? Or I have to figure it out by myself?
Thank you.
You might convert your array to a List<int[]> and call Collections.shuffle(). Then convert back to an array.
int array[][] = {{1, 2, 3}, {2, 5, 7}, {4, 2, 1}};
List<int[]> l = Arrays.asList( array ); //the list returned is backed by the array, and thus the array is shuffled in place
Collections.shuffle( l );
//no need to convert back
If you need to keep the original order, you'd have to create a copy of the array (or the list backed by that array), like this:
int array[][] = {{1, 2, 3}, {2, 5, 7}, {4, 2, 1}};
List<int[]> l = new ArrayList<int[]>( Arrays.asList( array ) ); //creates an independent copy of the list
Collections.shuffle( l );
int newArray[][] = l.toArray( new int[0][0] );
Another way:
int array[][] = {{1, 2, 3}, {2, 5, 7}, {4, 2, 1}};
int newArray[][] = array.clone(); //copy the array direcly
List<int[]> l = Arrays.asList( newArray );
Collections.shuffle( l );
It is very simple using the Collections.shuffle(..) method as the Arrays.asList(..) method returns a List backed by the array.
Collections.shuffle(Arrays.asList(array));
Full example:
public static void main(String... args) {
int array[][] = {{1, 2, 3}, {2, 5, 7}, {4, 2, 1}};
Collections.shuffle(Arrays.asList(array));
for (int[] a : array)
System.out.println(Arrays.toString(a));
}
If you can use collections there is a shuffle method, if you have to use a primitive type such as int, you will have to shuffle it yourself. Here are examples of both:
http://blog.ryanrampersad.com/2008/10/13/shuffle-an-array-in-java/
Try the Collections class that comes with Java. You can use the shuffle() method to randomize the indices to access the arrays.
Link to Java API
Use Collections:
something like this:
List<int[]> list = Arrays.asList(array);
Collections.shuffle(list);
int[][] shuffledArray = (int[][]) shuffledList.toArray();
What you want is random swaps of the contents of the outer array.
You could use java.Random's nextBoolean() to get a true/false as to whether to make a swap, such as between 1&2 or 1&3 or 2&3.
This is assuming you want to work with the primitive types, and not classes.

Categories