Let's that I have a number N. N will be the size of the array.
int numArray [] = new numArray[N];
However, the contents of the array will hold every other number from 1 to positive N. This means that the entire size N array will not be full after that for loop. So after the for loop, I want to trim (or resize) the array so that there will no longer be any empty slots in the array.
Example :
Let's say N = 5;
That means, after the for loop, every other number from 1 to 5 will be in the array like so:
int arr[] = new int[N];
int arr[0]=1;
int arr[1]=3;
int arr[2]= null;
int arr[3]= null;
int arr[4]= null;
Now, I want to trim (or resize) after the for loop so that the indexes that hold null will be gone and then the array should be:
int arr[0]=1;
int arr[1]=3;
The size of the array is now 2.
You can't trim an array. The fastest approach is just to copy it into a smaller one, using System.arraycopy, which is almost always much faster than a for loop:
int somesize = 5;
int[] numArray = new int[somesize];
//code to populate every other int into the array.
int[] smallerArray = new int[somesize/2];
//copy array into smaller version
System.arraycopy(numArray, 0, smallerArray, 0, somesize / 2);
You can't change the size of an array in Java after it has been created.
What you can do however, is to create a new array of the size that you need.
Another important point is that you are creating an array of a primitive: int. Primitives are not objects and you cannot assign the value null to a primitive.
You need to create an array of java.lang.Integer if you want to be able to set entries in it to null.
Integer[] numArray = new Integer[N];
Thanks to a Java feature called auto-boxing, almost all code that works with primitive int values, also works with Integer values.
Steps:
Use Integer[] instead of int[]
Calculate the size that you need (count non-null entries in original array)
Allocate a new array of the size that you need
Loop over the old array, and copy every non-null value from it to the new array.
Code:
Integer[] oldArray = ...;
// Step 2
int count = 0;
for (Integer i : oldArray) {
if (i != null) {
count++;
}
}
// Step 3
Integer[] newArray = new Integer[count];
// Step 4
int index = 0;
for (Integer i : oldArray) {
if (i != null) {
newArray[index++] = i;
}
}
I think there is a bit shorter way to do the trimming itself.
Whats left is to find the proper index.
You can do:
int someIndex = Arrays.asList(arr).indexOf(null);
arr = Arrays.copyOfRange(arr,0,someIndex);
You surely better of with some more appropriate data structure, for example a list or a set depending on what's your intention with it later. That way you don't even need to create an N sized structure just so you'd have to reduce it anyway. Rather you create an empty list and add the elements that you actually need
import java.util.Arrays;
public static void main( String[] args )
{
int[] nums2 = {9,4,1,8,4};
nums2 =Arrays.copyOf(nums2,3);
for (int i : nums2) {
System.out.print(i+" ");
}
}
//Output
9 4 1
Related
I have a problem with one of our old exam tasks.
the task is
"the method positions should return a field containing exactly the positions of those elements of the list that have null as content. if there are no such elements than return a field with the length 0"
the code starts with :
public int[] positions() {
int[] result = new int[0];
I keep getting stuck on because of the "new int[0]" when I tried solving the problem without it I managed to get somewhat of a result. but I don't know how to do it with this part.
Just think for a moment what the code is doing here.
int[] result = new int[0];
creates an empty, fixed lenght, primitive array. This array cannot be further expanded.
Your exam task would be translated as (simplifying at a large degree):
public int[] positions(final Object[] objects) {
// Initialize the array with the max possible size, which is the input array size
final int[] positions = new int[objects.lenght];
int j = 0;
for (int i = 0; i < objects.length; i++) {
if (objects[i] == null) {
// Assign the index of the null value to the holder array.
// Increment j, which is the index of the first free position in the holder array
positions[j++] = i;
}
}
// This will return a copy of the "positions" array, truncated at size j
return Array.copyOf(positions, j);
}
I'm having a bit of trouble understanding how arrays work, specifically when the array is not given a specific size. For example, if I'm given the code:
public int [][] someMethodHere(int [][] myNewArray) {
//code here
}
I want to know how I can create another array within the method with the same number of rows and columns in the parameter (WITHOUT just adding in some numerical value in the parameter and then just writing the same value in the new array. Thanks!)
An array has a fixed size that you set when you create the array.
This is different to many other data structures like List or Map that are "smart" and can handle resizing themselves when the need arises.
So when you create an array you must tell the compiler how big it is:
// create the original array with 10 slots
int[] originalArray = new int[10];
If you want to create a new array of the same size, you can use the length property of the Array type.
// create a new array of the same size as the original array
int[] newArray = new int[originalArray.length];
In your case of a 2-dimensional array, you could do it like this:
// create the original array
int[][] originalArray = new int[10][20];
// create a new array of the same size as the original array
int[][] newArray = new int[originalArray.length][originalArray[0].length];
Notice that when specifying the length of the second dimension, I get the length of the first element in the original array. This works as long as all the rows have the same length.
If the rows are of different length you could set the length of each row in the new array by iterating over the first dimension of the array like this:
// create a new array where the first dimension is the same size as the original array
int[][] newArray = new int[originalArray.length][];
// set the size of the 2nd dimension on a per row basis
for(int i = 0; i < originalArray.length; i++) {
newArray[i] = new int[originalArray[i].length];
}
You can make a copy of the array and clear the new array.
public static int[][] someMethodHere(int[][] src) {
int length = src.length;
int[][] target = new int[length][src[0].length];
for (int i = 0; i < length; i++) {
System.arraycopy(src[i], 0, target[i], 0, src[i].length);
Arrays.fill(target[i], 0);
}
return target;
}
Working in Java, suppose I have made a 2D array which is 30 by 50 units, like this:
public Array() {
int[][] array = new int[30][50];
}
and then I do this:
int rows = array.length;
int columns = array[1].length;
why does array.length get me a value of 30? Could the length not also be 50? Similarly, how then does array[1].length work out to be 50?
I have seen this answered elsewhere but I didn't understand the answer (beginner in Java here).
EDIT: This is how it was explained to me before, which I didn't understand. "when we refer to array.length, we get the length of the larger list, which is 30. When we refer to array[1].length, we get the length of the small list with index 1 in the large list, which is the second small list in the large list. This will have a value of 50."
If you rewrite to this, maybe it gets clearer
public Array() {
int[][] array = new int[30][];
array[0] = new int[50];
array[1] = new int[50];
// ... you may use a loop, but to make it explicit
array[29] = new int[50];
}
When you declare an array you MUST indicate at least the first dimension (30).
In your example all elements of the first dimension holds an array reference to an array with 50 elements.
You can have diferent lengths also:
public Array() {
int[][] array = new int[30][];
array[0] = new int[5];
array[1] = new int[7];
// ...
}
Consider this simple example
array[3][5];
array[number_of_row][number_of_column];
array[3][5] means 3*5 matrix which is
[0,0][0,1][0,2][0,3][0,4]
[1,0][1,1][1,2][1,3][1,4]
[2,0][2,1][2,2][2,3][2,4]
here you can clearly see that 3*5 matrix has 3 rows and 5 columns,
that's also means each row has 5 columns. So, array.length means
number of rows which is 3 and array[1].length means number of columns
in row position 1 which is 5
This logic is same as array[30][50]
First you need to know that a 2D array is actually a 1D array with each element in that array is another 1D array.
a[0] = [0][1][2][3]
a[1] = [0][1][2][3]
a[2] = [0][1][2][3]
a[3] = [0][1][2][3]
so length will get the length or the array being called at
i.e a.length will be the length of a, not the length of the array assigned at element 0 or 1 , ...n in a
also note the arrays created in each element of the 1D array a could be of different length. so calling a.length will not be accurate if always returned the length of 1st row i.e: a[0].length
int a[][] = new int[4][];
a[0] = new int [10];
a[1] = new int [7];
a[2] = new int [11];
a[3] = new int [30];
I want to declare an empty array in java and then I want do update it but the code is not working...
public class JavaConversion
{
public static void main(String args[])
{
int array[]={};
int number = 5, i = 0,j = 0;
while (i<4) {
array[i]=number;
i=i+1;
}
while (j<4) {
System.out.println(array[j]);
}
}
}
You are creating an array of zero length (no slots to put anything in)
int array[]={/*nothing in here = array with no elements*/};
and then trying to assign values to array elements (which you don't have, because there are no slots)
array[i] = number; //array[i] = element i in the array of length 0
You need to define a larger array to fit your needs
int array[] = new int[4]; //Create an array with 4 elements [0],[1],[2] and [3] each containing an int value
Your code compiles just fine. However, your array initialization line is wrong:
int array[]={};
What this does is declare an array with a size equal to the number of elements in the brackets. Since there is nothing in the brackets, you're saying the size of the array is 0 - this renders the array completely useless, since now it can't store anything.
Instead, you can either initialize the array right in your original line:
int array[] = { 5, 5, 5, 5 };
Or you can declare the size and then populate it:
int array[] = new int[4];
// ...while loop
If you don't know the size of the array ahead of time (for example, if you're reading a file and storing the contents), you should use an ArrayList instead, because that's an array that grows in size dynamically as more elements are added to it (in layman's terms).
You need to give the array a size:
public static void main(String args[])
{
int array[] = new int[4];
int number = 5, i = 0,j = 0;
while (i<4){
array[i]=number;
i=i+1;
}
while (j<4){
System.out.println(array[j]);
j++;
}
}
So the issue is in your array declaration you are declaring an empty array with the empty curly braces{} instead of an array that allows slots.
Roughly speaking, there can be three types of inputs:
int array[] = null; - Does not point to any memory locations so is a null arrau
int array[] = {} - which is sort of equivalent to int array[] = new int[0];
int array[] = new int[n] where n is some number indicating the number of
memory locations in the array
You can't set a number in an arbitrary place in the array without telling the array how big it needs to be. For your example: int[] array = new int[4];
You can do some thing like this,
Initialize with empty array and assign the values later
String importRt = "23:43 43:34";
if(null != importRt) {
importArray = Arrays.stream(importRt.split(" "))
.map(String::trim)
.toArray(String[]::new);
}
System.out.println(Arrays.toString(exportImportArray));
Hope it helps..
You can try creating new array at every iteration with a size greater than in the previous iteration.
i.e.
public class JavaConversion
{
public static void main(String args[])
{
int array[]=new int[0];
int number = 5, i = 0,j = 0;
while (i<4) {
array = Arrays.copyOf(array, array.length + 1);
array[i]=number;
i=i+1;
}
while (j<4) {
System.out.println(array[j]);
}
}
}
It is better for that operation use ArrayList
Is there a way where you can use Math.random to prints the element in a given array?
int[] list = new int[] {1,2,3};
So the output will be like
2,1,3
or
3,1,2
or
2,3,1
Perhaps you can approach it by shuffling your array then print it. If the original should not be modified, you can make a copy and then shuffle the copy.
There are well-known algorithms for shuffling array (or a deck of cards). One can be found here. An implementation in java looks like this:
static void shuffleArray(int []array) {
int length = array.length;
for (int i = length -1; i > 0; i--) {
// generate a random 0 <= j < i
int j = (int)(Math.random() * i);
// swap elements at i and j
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
The approach proposed in most answers is extremely inefficient, as it works in O(N2) time. Think about it: at first you'll generate unused indexes with one attempt, but closer to the end, when almost all array is processed, it will require nearly N steps to generate next unused index.
The optimal O(N) approach is to create shuffled array of indexes (0..N) where each index appears only once and then process your original array in the order of shuffled indexes. Each step requires O(N) time, so the whole algorithm is O(N).
int[] input = new int[]{5, 4, 3, 6, 2, 1};
int []indices = new int[input.length];
//Fisher-Yates shuffle
Random rnd = new Random();
for (int i = 0; i < indices.length; i++) {
int j = rnd.nextInt(i + 1);
indices[i] = indices[j];
indices[j] = i;
}
for (int i : indices) {
System.out.println(input[i]);
}
I didn't use Collections.shuffle, as it would require usage of Collection and thus wrapped Integer elements, which is very inefficient comparing to the plain int array.
Also, if you are ok with modifying your original array, you can just shuffle it in place (using the same Fisher-Yates shuffle) and then consume it while traversing.
UPD: Replaced shuffling array of indices with shuffled initialization.
Since you have java 8, you can take advantage of the beautiful Stream API.
In short, you can do:
new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));
Where 1 is the lowest int generated (inclusive) and 500 is the highest (exclusive). limit means that your stream will have a length of 500, maybe in that argument you want to put list.length.
For your case:
int[] list = new int[] {1,2,3,4,5,6};
new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p]));
Prints: 5 2 5 4 6 3 3 5 6 4 (Obviously will not print the same numbers for you)
Create a random integer that may be as high as the length of the array - 1. If the random integer is equal to a previous used random integer -- known by storing used integers in an array -- create a new random integer. Otherwise, print the string correlated with that index specified by the random integer. If the length of the array storing the used random integers is equal to the length of the array of strings, stop the process.
This should print all your strings only once each and randomly.
Here is the solution
public static void main(String[] args) {
int[] list = new int[] { 1, 2, 3 };
int[] aux = new int[list.length];
int countTimes = 0;
while (countTimes < list.length) {
int position = new Random().nextInt(list.length);
if (aux[position] != list[position]) {
System.out.println(list[position]);
aux[position] = list[position];
countTimes++;
}
}
}
As I said in the comments. This answer will work.. All you need to do is track the indices that it accessed so you don't repeat them or remove that element from the array.
void printRandom(int[] array) {
if (array.length == 0)
return;
Random rand = new Random();
int rnd = rand.nextInt(array.length);
int element = array[rnd];
array = ArrayUtils.removeElement(array, element);
System.out.print(element);
printRandom(array);
}
Just repeat this process until all elements are removed. Obviously add checks to prevent errors and keep in mind I haven't used JAVA in a long time so post back if you have issues!
Lastly keep in mind this deletes the array so you may want to wrap this code in a function and then copy the array as a local variable so you can reuse the original as needed
In this case we can print random value from array using like below :
Steps:
Create list object of Integer to hold printed indices
Get random number and check whether this index is already printed or not
if not printed then add it in list and print value from array using this index
if list size and array length is equal then terminate the loop
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RandomIndices {
public static void main(String[] args) {
int[] list = new int[]{1, 2, 3};
Random random = new Random();
List<Integer> randomIndices = new ArrayList<>(); //to hold indices which are already printed
boolean isRemain = true;
while (isRemain) {
int randomIndex = random.nextInt(list.length);
if (!randomIndices.contains(randomIndex)) { //check random index value of array is printed or not
randomIndices.add(randomIndex);
System.out.println(list[randomIndex]);
}
if (randomIndices.size() == list.length) {
isRemain = false;
}
}}
}
Implement a simple "do while" statement to prevent duplicate numbers from showing up out of your array (I used a StringArray - but an IntegerArray would work the same way - as a side note, I can place the complete code up here but didn't want to do so if it didn't apply. I use a drop-down to select how many random words to generate - then display that set of true RANDOM words (non-repeated):
final Random rand1 = new Random();
final Random rand2 = new Random();
final int rndInt1 = rand1.nextInt(getResources().getStringArray(R.array.words).length);
int rndInt2 = rand2.nextInt(getResources().getStringArray(R.array.words).length);
if (rndInt1 == rndInt2){
do {
rndInt2 = rand2.nextInt(getResources().getStringArray(R.array.words).length);
}while (rndInt1 == rndInt2);//if indexes are equal - re-run the array search
}
outString = getResources().getStringArray(R.array.words)[rndInt1];
outString += ", " + getResources().getStringArray(R.array.words)[rndInt2];//concatenate the list
textWord = (TextView) findViewById(R.id.textWords);//An empty text field in my layout
textWord.setText(outString);//Set that empty text field to this string of random array elements