defining an array size without hardcoding in Java - java

I'm having a problem where I cannot initialize an array without hard-coding it in Java.
So this is the hard-code version which works:
int numberOfElements = inputFromFile(args[0], myArray);
int [] myArray = new int[1000];
inputFromFile is basically going to be a method I'm going to write that can read the numberOfElements from a textfile along with my program.
I tried fixing it without hardcoding and got my result to be this:
int numberOfElements = inputFromFile(args[0], myArray);
int [] myArray = new int[numberOfElements];
Problem remains that Eclipse wants me to initialize myArray which is an integer array. Is there any good fixes without hard-coding? Any suggestion would be great.

Use an ArrayList, instead? Java, like C, requires constant sized arrays.

You need to initialize an array before using. You are aware of that, i assume.
If you dont know the size of your data, ie: you wont know how big the array size will be, then you will need to use ArrayList<T> which uses array internally and manages reallocation of array size for you.
If you have to use an array, you will have to maintain the array size yourself. as the array grows, you might run out of buckets if you dont set up enough space for the data ie: IndexOutOfBoundsException etc. Then you need to create a new array copy the content of the current array and then continue. All this is done for you in ArrayList, that s the benefit. Saves you time and implementation. Moreover, there is a concept called load factor which is used to expand the array.
Load factor for array is usually:
(j * 3) / 2 + 1 // j for the current length of the array.
FYI: Copying of array becomes very expensive if you data grows very big.
int numberOfElements = inputFromFile(args[0], myArray);
int [] myArray = new int[1000];
By looking at your code, your order of statements is wrong and should be :
int [] myArray = new int[1000];
int numberOfElements = inputFromFile(args[0], myArray);
you are passing myArray to a method before declaring and initializing it.
ArrayList<Integer> s = new ArrayList<Integer>();
int numberOfElements = inputFromFile(args[0], myArray);
This would be better. Then you need to change your method signature as follows:
public void inputFromFile(String fileName, ArrayList<Integer> collection){
// your impl.
}

The various way to use and declare arrays: http://leepoint.net/notes-java/data/arrays/arrays.html

I think you are getting the error because
1) you are using myArray before it is declared.
2) return type of the function inputFromFile does not match int.
I think the following program will answer your question. Here I have a int identifier 'm' which is getting set to a value returned by the 'getNumber' method. Then I am declaring an array of size m.
public class Practise {
public static void main(String args[]){
int m = getNumber();
int [] a = new int[m];
for(int i = 0; i < m; i++)
System.out.println(a[i]);
}
public static int getNumber(){
Scanner input = new Scanner(System.in);
int i = 0;
i = input.nextInt();
return i;
}
}

You can provide the size of your array as command line argument.
Using Dependency Injection of Spring can also be a good way to go, I hope you know how to write a simple bean (constructor injection / setter injection ).

Neither of your code blocks will work, as you try to use myArray before it's declared, or else you try to redeclare myArray. Other than that, if by "hardcode" you mean use a literal value, then no, you don't have to do that. Any of these will work:
int[] arr1 = new int[5];
int size = 10;
int[] arr2 = new int[size];
int sizeLoadedFromFile = loadSizeFrom("/foo/bar/baz");
int[] arr3 = new int[sizeLoadedFromFile];
Note you can also declare an array without an explicit "size" argument if you know the elements ahead of time:
int[] arr4 = {1, 2, 3, 4};
If you think you want an array, but you don't know the size ahead of time, then what you really want is some kind of Collection--probably a List:
List<Integer> list1 = new ArrayList();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
or more readably, again if you know the elements ahead of time:
List<Integer> list2 = new ArrayList() {{
add(1); add(2); add(3); add(4);
}};
or
List<Integer> list3 = Arrays.asList(1, 2, 3, 4, 5);
The Collections Tutorial should tell you anything else you need to know.

An alternative to using List<Integer> is to use the Trove4j TIntArrayList. This is effectively a wrapper for int[].
However, ArrayList<Integer> is usually fast enough for most use cases.

Related

Convert ArrayList to Int [] array using .toArray()? Or...?

So, this is part of a method which checks for available rooms within a date range and is meant to return the int [] array of room numbers which are available.
ArrayList roomNums = new ArrayList();
roomNums.toArray();
for (Room room: rooms){
int roomNumber = room.getRoomNumber();
if(room.getRoomType() == roomType && isAvailable(roomNumber, checkin, checkout)){ // This works fine, ignore it
roomNums.add(roomNumber);
}
}
return roomNums.toArray(); // Error here, return meant to be int [] type but it's java.lang.Obeject []
The error occurs at the end at roomNums.toArray()
I saw someone else do this one liner and it worked for them, why is it not for me?
Every element in roomNums is an integer. (I think)
What's the quickest and easiest way to print an integer array containing the available rooms? Do I need to make a loop or can I do something with this .toArray() one liner or something similar to it?
Thanks
Don't use raw types. Replace ArrayList roomNums = new ArrayList(); with
ArrayList<Integer> roomNums = new ArrayList<>();
Then return it as Integer[]
roomNums.toArray(Integer[]::new);
If you need primitive array, then it can be done with stream:
return roomNums.stream().mapToInt(Integer::valueOf).toArray();
See also How to convert an ArrayList containing Integers to primitive int array?
Unfortunately, you will need to use Integer[] if you want to use toArray
List<Integer> roomNums = new ArrayList<>();
// code here
Integer[] arr = new Integer[roomNums.size()];
return roomNums.toArray (arr);
However you can still do it manually like
List<Integer> roomNums = new ArrayList<> ();
// code here
int[] arr = new int[roomNums.size()];
for (int i = 0; i < arr.length; i++)
arr[i] = roomNums.get (i);
return arr;
As mentioned above use the ArrayList to hold your values:
ArrayList<Integer> roomNums = new ArrayList<>();
then you can use the object super class to convert to array
Object[] numbersArray = roomNums.toArray();
then just continue running the for loop and your program

How to create a nested array of arbitrary depth in java?

I am trying to create an array of arrays of arrays etc..., except I don't know how many nested levels deep it needs to be until runtime.
Depending on the input, I might need either int[], int[][], int[][][][][][], or anything else. (For context, I am trying to construct an N-dimensional grid for a cellular automaton, where N is passed as a parameter.)
I don't have any code for you because I have no idea how to go about this; I suspect is not possible at all using just arrays. Any help, or alternative solutions, would be appreciated.
You could do this with an Object[], limiting its members to either Object[] or int[].
For example, here's an array that goes three levels deep in one part, and two levels deep in another:
Object[] myarray = new Object[] {
new Object[] { new int[] { 1, 2 },
new int[] { 3, 4 }},
new int[] { 5, 6 }
};
After you've created it, you may want to access members. In your case, you know the depth N up front, so you know at what depth to expect an Object[] and at what depth to expect an int[].
However, if you didn't know the depth, you could use reflection to determine whether a member is another Object[] level or a leaf int[].
if ( myarray[0] instanceof Object[] ) {
System.out.println("This should print true.");
}
EDIT:
Here's a sketch [untested so far, sorry] of a method that access a member of an array of known depth, given an array of indices. The m_root member can be an Object[] or an int[]. (You could relax this further to support scalars.)
public class Grid {
private int m_depth;
private Object m_root;
...
public int get( int ... indices ) {
assert( indices.length == m_depth );
Object level = m_root;
for ( int i = 0; i + 1 < m_depth; ++i ) {
level = ((Object[]) level)[ indices[i] ];
}
int[] row = (int[]) level;
return row[ indices[m_depth - 1] ];
}
}
This should be achievable using Object[], since arrays are objects:
int[] arr = {1,2,3};
int[] arr2 = {1,2,3};
int[] arr3 = {1,2,3};
int[] arr4 = {1,2,3};
Object[] arr5 = {arr, arr2}; // basically an int[][]
Object[] arr6 = {arr3, arr4}; // basically an int[][]
Object[] arr7 = {arr5, arr6}; // basically an int[][][]
// etc.
Note that one array doesn't have to contain arrays of the same dimensions:
Object[] arr7 = {arr5, arr};
To prevent this (and to allow for easier access to the data), I suggest writing a class which has an Object member (which will be your int[] or Object[]) and a depth variable and some nice functions to give you access to what you want.
ArrayLists will also work:
ArrayList array = new ArrayList();
array.add(new ArrayList());
array.add(new ArrayList());
((ArrayList)array.get(0)).add(new ArrayList());
// etc.
As your N increases going with nested arrays becomes less and less advantageous, especially when you have a grid structure. Memory usage goes up exponentially in N with this approach and the code becomes complex.
If your grid is sparsely populated (a lot of cells with the same value) you can instead have a collection of Cell objects where each of these holds a coordinate vector and the integer value of the cell. Every cell that is not in the collection is assumed to have a default value, which is your most common value.
For faster access you can use for example a k-d tree (https://en.wikipedia.org/wiki/K-d_tree) but that depends a bit on your actual use-case.
#Andy Thomas explains how to do this using Object[] for the higher levels of the multidimensional array. Unfortunately, this means that the types are not correct to allow indexing, or indeed to allow element access without typecasts.
You can't do this:
Object[] array = ...
int i = array[1][2][3][4];
To get types that allow you to do the above, you need to create an object whose real type is (for example) int[][][][].
But the flipside is that it is not really practical to use that style of indexing for N dimensional arrays where N is a variable. You can't write Java source code to do that unless you place a bound on N (i.e. up to 5) and treat the different cases individually. That becomes unmanageable very quickly.
You can use Java reflection as Arrays are objects.
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException {
Class<?> intClass = int.class;
Class<?> oneDimensionalArrayClass = Class.forName("[I");
Object oneDimensionalIntArray1 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray1, 0, 1);
Object oneDimensionalIntArray2 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray2, 0, 2);
Object oneDimensionalIntArray3 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray3, 0, 3);
Object twoDimensionalIntArray = Array.newInstance(oneDimensionalArrayClass, 3);
Array.set(twoDimensionalIntArray, 0, oneDimensionalIntArray1);
Array.set(twoDimensionalIntArray, 1, oneDimensionalIntArray2);
Array.set(twoDimensionalIntArray, 2, oneDimensionalIntArray1);
System.out.println(Array.get(Array.get(twoDimensionalIntArray, 1), 0));
}
The class Array with its static methods gives access on items while you can specify the dimension of your arrays with the number of leading "[".
The whole construct of multi-dimensional arrays is just the compiler doing some work for you on a big block of memory (ok as some have commented in java this is multiple blocks of memory). One way to deal with the problem you face is to use nested arraylists at runtime. Another (more performant) way is to just allocate a single-dimensional array of the size you need and do the indexing yourself. You could then hide the indexing code in a method that was passed all the details like an array de-reference.
private int[] doAllocate(int[] dimensions)
{
int totalElements = dimensions[0];
for (int i=1; i< dimensions.length; i++)
{
totalElements *= dimensions[i];
}
int bigOne = new int[totalElements];
return bigOne;
}
private int deReference(int[] dimensions, int[] indicies, int[] bigOne)
{
int index = 0;
// Not sure if this is only valid when the dimensions are all the same.
for (int i=0; i<dimensions.length; i++)
{
index += Math.pow(dimensions[i],i) * indicies[dimensions.length - (i + 1)];
}
return bigOne[index];
}
Fields like you wrote above a checked and created by the compiler. If you want a dynamic data structure during runtime you could create your own data structure. Search for Composite Pattern. A small snippet should show you how it works:
interface IGrid {
void insert(IGrid subgrid);
void insert(int[] values);
}
class Grid implements IGrid {
private IGrid subgrid;
void insert(IGrid subgrid) {this.subgrid = subgrid;}
void insert(int[] values) {/* Do nothing */}
}
class SubGrid implements IGrid {
private int[] values;
void insert(IGrid subgrid) {/* Do nothing */}
void insert(int[] values) {this.values = values;}
}
You could simply create a Subgrid for int[] or a Grid with a Subgrid for int[][]. It's only a rudimental solution, you would have to create some code for working on your automaton's levels and values. I would do it this way. Hope it will help :) And look forward for more solutions^^

Remove a specific string from an array of string

I have an array like this:
String n[] = {"google","microsoft","apple"};
What I want to do is to remove "apple".
My problem is very basic,however,I searched the website and I found out that java doesn't really support the deleting feature from an array.I also heard to use Java Utils, because it's so simple to remove an item....I tried to find Java Utils on google, but almost all links are dead.
So finally...is there any way to remove a string from an array of string?
Even if I use an ArrayList I can't find a method to generate a random item in it! For ex: in a normal array I generate a string like this:
String r = myAL[rgenerator.nextInt(myAL.length)];
In an arraylist it doesn't work....maybe you know a solution...
Define "remove".
Arrays are fixed length and can not be resized once created. You can set an element to null to remove an object reference;
for (int i = 0; i < myStringArray.length(); i++)
{
if (myStringArray[i].equals(stringToRemove))
{
myStringArray[i] = null;
break;
}
}
or
myStringArray[indexOfStringToRemove] = null;
If you want a dynamically sized array where the object is actually removed and the list (array) size is adjusted accordingly, use an ArrayList<String>
myArrayList.remove(stringToRemove);
or
myArrayList.remove(indexOfStringToRemove);
Edit in response to OP's edit to his question and comment below
String r = myArrayList.get(rgenerator.nextInt(myArrayList.size()));
It is not possible in on step or you need to keep the reference to the array.
If you can change the reference this can help:
String[] n = new String[]{"google","microsoft","apple"};
final List<String> list = new ArrayList<String>();
Collections.addAll(list, n);
list.remove("apple");
n = list.toArray(new String[list.size()]);
I not recommend the following but if you worry about performance:
String[] n = new String[]{"google","microsoft","apple"};
final String[] n2 = new String[2];
System.arraycopy(n, 0, n2, 0, n2.length);
for (int i = 0, j = 0; i < n.length; i++)
{
if (!n[i].equals("apple"))
{
n2[j] = n[i];
j++;
}
}
I not recommend it because the code is a lot more difficult to read and maintain.
Arrays in Java aren't dynamic, like collection classes. If you want a true collection that supports dynamic addition and deletion, use ArrayList<>. If you still want to live with vanilla arrays, find the index of string, construct a new array with size one less than the original, and use System.arraycopy() to copy the elements before and after. Or write a copy loop with skip by hand, on small arrays the difference will be negligible.
You can't remove anything from an array - they're always fixed length. Once you've created an array of length 3, that array will always have length 3.
You'd be better off with a List<String>, e.g. an ArrayList<String>:
List<String> list = new ArrayList<String>();
list.add("google");
list.add("microsoft");
list.add("apple");
System.out.println(list.size()); // 3
list.remove("apple");
System.out.println(list.size()); // 2
Collections like this are generally much more flexible than working with arrays directly.
EDIT: For removal:
void removeRandomElement(List<?> list, Random random)
{
int index = random.nextInt(list.size());
list.remove(index);
}
import java.util.*;
class Array {
public static void main(String args[]) {
ArrayList al = new ArrayList();
al.add("google");
al.add("microsoft");
al.add("apple");
System.out.println(al);
//i only remove the apple//
al.remove(2);
System.out.println(al);
}
}

How to copy a subset from an array of strings to an array of ints using Groovy?

I have a String array in a Groovy class (args to a main method):
String[] args
I'd like to convert the 3rd to the last element into a new array of ints. Is there an easier way to do this in Groovy other than:
final int numInts = args.length - 2
final int [] intArray = new int[numInts]
for (int i = 2; i < args.length; i++) {
intArray[i-2]=Integer.parseInt(args[i])
}
I wanted to do:
final int numInts = args.length - 2
final int [] intArray = new int[numInts]
System.arraycopy(args, 2, intArray, 0, numInts)
But it throws a class cast exception.
Thanks!
This is my solution:
def intArray = args[2..-1].collect { it as int } as int[]
The 2..-1 range selects all elements from the 3rd to the last. The collect method transforms every element of the array using the code in the closure. The last as int[] converts the List of integers that results from the collect method into an array of integers. As Groovy doesn't work with primitive types, the ints will always be stored as java.lang.Integers, but you can work with them, as if they were Java primitives. The conversion from a List to an array is optional. As Collections are first class citizens in Groovy and are much easier to work with as in Java, I'd prefer to work directly with Lists than arrays.
EDIT:
Alternatively, you can replace the collect method with the so called spread operator *., but you have to use the method asType(int) instead of the short version as int:
def intArray = args[2..-1]*.asType(int) as int[]
For your alternative - you try to copy String objects to integers. That is not possible and you get what you deserve - a ClassCastException ;-)
At least within Java - System.arraycopy only works with compatible array types.
Your first approach is not bad. If the code looks too ugly, just hide it in a private method with a signature like:
private int[] parseStrings(String[] args, int start);

in java can one have an array of variables?

in java can you have an array of variables?
if so what is the syntax?
here's an example if your confused:
varint[] ArrayOfVariablesThatAreInts = new varint[#]
or
var[] ArrayofVariables = new var[#]
is something like this legal?
Yes you can use:
Foo[] arrFoo = new Foo[10];
arrFoo[0] = new Foo();
..
Or if you dont want to define a fix size, you can use an ArrayList:
List<Foo> arrFoos = new ArrayList<Foo>();
arrFoos.add(new Foo());
..
To create an array of ints for example you would use:
int[] array = new int[size];
Where size is how big you want the array to be.
Sure. You can do something like:
String[] arrayOfStrings = new String[10];
Not really.
You can have an array of int values though:
int[] intArray = new int[100]; // array to hold 100 int's
But you can't use them as variables, you'll have to use them as values.
intArray[0] = 512;// set's the first element in the array to 512
int someIntVariable = intArray[0]; // get the first element in the array ( 512 ) .
Arrays are fixed size ( once allocated can't shrink or grow ) to do that you should use a List ( variable size ) of ints:
List<Integer> list = new ArrayList<Integer>(); // Integer is a wrapper for int
list.add(512);
list.add(1024);
int x = list.get(0);// get the first element in the list ( 512 )
I'm not sure if this is what you mean by a array of variables but see if this is what your looking for.
import java.util.ArrayList;
public class StackQuestion {
private static int random1 = 1;
private static int random2 = 2;
public static void main(String [] args){
ArrayList a1 = new ArrayList();
a1.add(random1);
a1.add(random2);
System.out.println(a1.get(0));
System.out.println(a1.get(1));
}
}
In java you can have arrays of a specific type (like string, int or any object). You can use this array positions to store variables if you want to store them in an array. Or alternatively you can create an object array which can store variables of different types.
The length of the array needs to be pre defined and if that doesn't suit you,you can use any cooleciton like ArrayList

Categories