I have a class - xClass, that I want to load into an array of xClass so I the declaration:
xClass mysclass[] = new xClass[10];
myclass[0] = new xClass();
myclass[9] = new xClass();
However, I don't know if I will need 10. I may need 8 or 12 or any other number for that matter. I won't know until runtime.
Can I change the number of elements in an array on the fly?
If so, how?
No you can't change the size of an array once created. You either have to allocate it bigger than you think you'll need or accept the overhead of having to reallocate it needs to grow in size. When it does you'll have to allocate a new one and copy the data from the old to the new:
int[] oldItems = new int[10];
for (int i = 0; i < 10; i++) {
oldItems[i] = i + 10;
}
int[] newItems = new int[20];
System.arraycopy(oldItems, 0, newItems, 0, 10);
oldItems = newItems;
If you find yourself in this situation, I'd highly recommend using the Java Collections instead. In particular ArrayList essentially wraps an array and takes care of the logic for growing the array as required:
List<XClass> myclass = new ArrayList<XClass>();
myclass.add(new XClass());
myclass.add(new XClass());
Generally an ArrayList is a preferable solution to an array anyway for several reasons. For one thing, arrays are mutable. If you have a class that does this:
class Myclass {
private int[] items;
public int[] getItems() {
return items;
}
}
you've created a problem as a caller can change your private data member, which leads to all sorts of defensive copying. Compare this to the List version:
class Myclass {
private List<Integer> items;
public List<Integer> getItems() {
return Collections.unmodifiableList(items);
}
}
In java array length is fixed.
You can use a List to hold the values and invoke the toArray method if needed
See the following sample:
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
public class A {
public static void main( String [] args ) {
// dynamically hold the instances
List<xClass> list = new ArrayList<xClass>();
// fill it with a random number between 0 and 100
int elements = new Random().nextInt(100);
for( int i = 0 ; i < elements ; i++ ) {
list.add( new xClass() );
}
// convert it to array
xClass [] array = list.toArray( new xClass[ list.size() ] );
System.out.println( "size of array = " + array.length );
}
}
class xClass {}
As others have said, you cannot change the size of an existing Java array.
ArrayList is the closest that standard Java has to a dynamic sized array. However, there are some things about ArrayList (actually the List interface) that are not "array like". For example:
You cannot use [ ... ] to index a list. You have to use the get(int) and set(int, E) methods.
An ArrayList is created with zero elements. You cannot simple create an ArrayList with 20 elements and then call set(15, foo).
You cannot directly change the size of an ArrayList. You do it indirectly using the various add, insert and remove methods.
If you want something more array-like, you will need to design your own API. (Maybe someone could chime in with an existing third party library ... I couldn't find one with 2 minutes "research" using Google :-) )
If you only really need an array that grows as you are initializing it, then the solution is something like this.
ArrayList<T> tmp = new ArrayList<T>();
while (...) {
tmp.add(new T(...));
}
// This creates a new array and copies the element of 'tmp' to it.
T[] array = tmp.toArray(new T[tmp.size()]);
You set the number of elements to anything you want at the time you create it:
xClass[] mysclass = new xClass[n];
Then you can initialize the elements in a loop. I am guessing that this is what you need.
If you need to add or remove elements to the array after you create it, then you would have to use an ArrayList.
You can use ArrayList:
import java.util.ArrayList;
import java.util.Iterator;
...
ArrayList<String> arr = new ArrayList<String>();
arr.add("neo");
arr.add("morpheus");
arr.add("trinity");
Iterator<String> foreach = arr.iterator();
while (foreach.hasNext()) System.out.println(foreach.next());
As other users say, you probably need an implementation of java.util.List.
If, for some reason, you finally need an array, you can do two things:
Use a List and then convert it to an array with myList.toArray()
Use an array of certain size. If you need more or less size, you can modify it with java.util.Arrays methods.
Best solution will depend on your problem ;)
Arrays.copyOf() method has many options to fix the problem with Array length increasing dynamically.
Java API
Yes, wrap it and use the Collections framework.
List l = new ArrayList();
l.add(new xClass());
// do stuff
l.add(new xClass());
Then use List.toArray() when necessary, or just iterate over said List.
I recommend using vectors instead. Very easy to use and has many predefined methods for implementation.
import java.util.*;
Vector<Integer> v=new Vector<Integer>(5,2);
to add an element simply use:
v.addElement(int);
In the (5,2) the first 5 is the initial size of the vector. If you exceed the initial size,the vector will grow by 2 places. If it exceeds again, then it will again increase by 2 places and so on.
Where you declare the myclass[] array as :
xClass myclass[] = new xClass[10]
, simply pass in as an argument the number of XClass elements you'll need. At that point do you know how many you will need? By declaring the array as having 10 elements, you are not declaring 10 XClass objects, you're simply creating an array with 10 elements of type xClass.
Java Array sizes are fixed , You cannot make dynamic Arrays as that of in C++.
Yes, we can do this way.
import java.util.Scanner;
public class Collection_Basic {
private static Scanner sc;
public static void main(String[] args) {
Object[] obj=new Object[4];
sc = new Scanner(System.in);
//Storing element
System.out.println("enter your element");
for(int i=0;i<4;i++){
obj[i]=sc.nextInt();
}
/*
* here, size reaches with its maximum capacity so u can not store more element,
*
* for storing more element we have to create new array Object with required size
*/
Object[] tempObj=new Object[10];
//copying old array to new Array
int oldArraySize=obj.length;
int i=0;
for(;i<oldArraySize;i++){
tempObj[i]=obj[i];
}
/*
* storing new element to the end of new Array objebt
*/
tempObj[i]=90;
//assigning new array Object refeence to the old one
obj=tempObj;
for(int j=0;j<obj.length;j++){
System.out.println("obj["+j+"] -"+obj[j]);
}
}
}
Since ArrayList takes to much memory when I need array of primitive types, I prefer using IntStream.builder() for creating int array (You can also use LongStream and DoubleStream builders).
Example:
Builder builder = IntStream.builder();
int arraySize = new Random().nextInt();
for(int i = 0; i<arraySize; i++ ) {
builder.add(i);
}
int[] array = builder.build().toArray();
Note: available since Java 8.
It is a good practice get the amount you need to store first then initialize the array.
for example, you would ask the user how many data he need to store and then initialize it, or query the component or argument of how many you need to store.
if you want a dynamic array you could use ArrayList() and use al.add(); function to keep adding, then you can transfer it to a fixed array.
//Initialize ArrayList and cast string so ArrayList accepts strings (or anything
ArrayList<string> al = new ArrayList();
//add a certain amount of data
for(int i=0;i<x;i++)
{
al.add("data "+i);
}
//get size of data inside
int size = al.size();
//initialize String array with the size you have
String strArray[] = new String[size];
//insert data from ArrayList to String array
for(int i=0;i<size;i++)
{
strArray[i] = al.get(i);
}
doing so is redundant but just to show you the idea, ArrayList can hold objects unlike other primitive data types and are very easy to manipulate, removing anything from the middle is easy as well, completely dynamic.same with List and Stack
I don't know if you can change the size at runtime but you can allocate the size at runtime. Try using this code:
class MyClass {
void myFunction () {
Scanner s = new Scanner (System.in);
int myArray [];
int x;
System.out.print ("Enter the size of the array: ");
x = s.nextInt();
myArray = new int[x];
}
}
this assigns your array size to be the one entered at run time into x.
Here's a method that doesn't use ArrayList. The user specifies the size and you can add a do-while loop for recursion.
import java.util.Scanner;
public class Dynamic {
public static Scanner value;
public static void main(String[]args){
value=new Scanner(System.in);
System.out.println("Enter the number of tests to calculate average\n");
int limit=value.nextInt();
int index=0;
int [] marks=new int[limit];
float sum,ave;
sum=0;
while(index<limit)
{
int test=index+1;
System.out.println("Enter the marks on test " +test);
marks[index]=value.nextInt();
sum+=marks[index];
index++;
}
ave=sum/limit;
System.out.println("The average is: " + ave);
}
}
In Java Array Sizes are always of Fixed Length But there is way in which you can Dynamically increase the Size of the Array at Runtime Itself
This is the most "used" as well as preferred way to do it-
int temp[]=new int[stck.length+1];
for(int i=0;i<stck.length;i++)temp[i]=stck[i];
stck=temp;
In the above code we are initializing a new temp[] array, and further using a for loop to initialize the contents of the temp with the contents of the original array ie. stck[]. And then again copying it back to the original one, giving us a new array of new SIZE.
No doubt it generates a CPU Overhead due to reinitializing an array using for loop repeatedly. But you can still use and implement it in your code.
For the best practice use "Linked List" instead of Array, if you want the data to be stored dynamically in the memory, of variable length.
Here's a Real-Time Example based on Dynamic Stacks to INCREASE ARRAY SIZE at Run-Time
File-name: DStack.java
public class DStack {
private int stck[];
int tos;
void Init_Stck(int size) {
stck=new int[size];
tos=-1;
}
int Change_Stck(int size){
return stck[size];
}
public void push(int item){
if(tos==stck.length-1){
int temp[]=new int[stck.length+1];
for(int i=0;i<stck.length;i++)temp[i]=stck[i];
stck=temp;
stck[++tos]=item;
}
else
stck[++tos]=item;
}
public int pop(){
if(tos<0){
System.out.println("Stack Underflow");
return 0;
}
else return stck[tos--];
}
public void display(){
for(int x=0;x<stck.length;x++){
System.out.print(stck[x]+" ");
}
System.out.println();
}
}
File-name: Exec.java
(with the main class)
import java.util.*;
public class Exec {
private static Scanner in;
public static void main(String[] args) {
in = new Scanner(System.in);
int option,item,i=1;
DStack obj=new DStack();
obj.Init_Stck(1);
do{
System.out.println();
System.out.println("--MENU--");
System.out.println("1. Push a Value in The Stack");
System.out.println("2. Pop a Value from the Stack");
System.out.println("3. Display Stack");
System.out.println("4. Exit");
option=in.nextInt();
switch(option){
case 1:
System.out.println("Enter the Value to be Pushed");
item=in.nextInt();
obj.push(item);
break;
case 2:
System.out.println("Popped Item: "+obj.pop());
obj.Change_Stck(obj.tos);
break;
case 3:
System.out.println("Displaying...");
obj.display();
break;
case 4:
System.out.println("Exiting...");
i=0;
break;
default:
System.out.println("Enter a Valid Value");
}
}while(i==1);
}
}
Hope this solves your query.
You can do some thing
private static Person [] addPersons(Person[] persons, Person personToAdd) {
int currentLenght = persons.length;
Person [] personsArrayNew = Arrays.copyOf(persons, currentLenght +1);
personsArrayNew[currentLenght] = personToAdd;
return personsArrayNew;
}
You can create array with variable containing length. Like new int[n]. And pass n dynamically as argument to method. You can also create array with maximum size you can possibly need. And also create variable to track current size. depends on what your usage is.
I am creating a class to sort some data.
class data{
public String text;
public String day;
public String direction;
}
dados vetor[]={};
Now I have to have to change a varible and I am doing it this way:
vetor[0].text="dumb text";
But I am gettting this error:
Attempt to write to field java.lang.String on a null object reference
Unless you reassigned the array to something else, this is your problem.
dados vetor[]={};
You create an empty array - there is no data object at vetor[0] for you to set the text of. If you know the number of elements you'll have when you declare the array, you can use the following to create an array to hold all of them.
dados[] vetor = new dados[10];
To actually create an element in that array and set its text, you need to create a new object.
vetor[0] = new data();
vetor[0].text = "Some text";
Alternatively, create and set the values for the data object before adding it to the array:
data myData = new data();
myData.text = "Some text";
vetor[0] = myData;
You probably did something like :
vetor[0] = someInstanceOfData.text; // Store value in array
However now vetor[0] contains the value of the text field (i.e. a String).
You can not access the text field later by doing vetor[0]. This refers to the String that is stored in that array. So if later the value of the text field changes, the vector will still contain the old.
Hence vetor[0].text="dumb text"; is not assigning the text field of some instance of the data class, but instead is trying to assign a new value to the String that results from vetor[0].
EDIT : If you want to change the value of the text field :
Data test = new Data(); // Make an instance of the Data class
test.text = "A String"; // Assign a value
If you want to make an array (of strings? or data objects?)
Data[] arr = {new Data(), new Data(), new Data()}; // Using the litteral
String[] arrOfStrings = {test.text, test.day, test.direction};
If you want to access/assign e.g. text from a data object storen in arr
arr[0].text = "Another String";
arrOfStrings[0].text = ...; // Not possible because it is storing strings not Data objects!
If you don't know the length before hand, you can not use an array (as they are of fixed length). Instead you could use List's which are of variable length.
List<Integer> test = new ArrayList<Integer>();
test.add(1); // Add elements
test.size(); // How long is my array at the moment?
test.get(0); // Access first element (index 0) --> 1
Applying this to your code :
dados testObject = new dados(); // create a "dados" object
List<dados> testList = new ArrayList<dados>();
testList.add(testObject);
testList.get(0); // Get object on index 0 (hence the first), hence "testObject"
To sort the ArrayList of dados objects you should implement a custom comparator to sort the objects like you want
public class OwnComparator implements Comparator<Dados> {
#Override
public int compare(Dados obj1, Dados obj2) {
return obj1.text.compareTo(obj2.text); // Sort based on "text" field
}
}
The actual sorting
Collections.sort(testList, new OwnComparator());
I am assuming your class name is "dados" and not "data".
Your array does not have any elements, hence the error.
Initialize your array to a certain number of elements and then assign the text property.
dados[] vetor = new dados[10];
vetor[0] = new dados();
vetor [0].text = "xx";
dados[] vetor2 = {new dados(), new dados()}; // initialize to 2 elements
vetor2[0].text = "xx";
i have arraylists named sub and main,
ArrayList main = new ArrayList();
ArrayList sub=new ArrayList();
i add value to sub and then add sub to main.
example;
sub.add(1);
sub.add(2);
main.add(sub);
now i want to get all values inside sub
so i used following one but .get(j) gives me the error get >> canot find symbol
for (int i=0;i<main.size();i++) {
System.out.println();
for (int j=0;j<sub().size();j++) {
System.out.print(main.get(i).get(j));//error line
}
}
how can i get all values inside subarray of main arraylist
When you declare a variable as
ArrayList main;
This list holds Objects. This means that main.get(i) will only return an Object, even if you add ArrayLists. That's why you get a compiler error: Object doesn't have a method named get().
To fix the problem, you need to use generics:
ArrayList<List<Integer>> main = new ArrayList<>();
ArrayList<Integer> sub=new ArrayList<>();
Now get() will return a List<Integer> which has a get() method, so the compiler error will disappear.
Generics could be your friend here:
ArrayList<ArrayList<Object>> main = new ArrayList<ArrayList<Object>>(); // or new ArrayList<>(); in Java 7+
ArrayList<Object> sub = new ArrayList<Object>(); // or new ArrayList<>();
If you can't or don't want to use generics, the solution is to cast the expression main.get(i) to an ArrayList first:
System.out.println(((ArrayList) main.get(i)).get(j));
Go through the following code
public class ArrayListDemo {
public static void main(String[] args) {
List<List<Integer>> main = new ArrayList<>();
List<Integer> sub = new ArrayList<>();
sub.add(1);
sub.add(2);
main.add(sub);
//If you want to get values in sub array list
for(int i = 0; i < 1; i++){
List<Integer> arr = main.get(i);
for(Integer val : arr) System.out.println(val + "");
}
//If you want to print all values
for(List<Integer> list : main){
for(Integer val : list) System.out.println(val + "");
}
}
}
In the above code, I had declared an ArrayList (main) to keep all Array which are having Integer values. Also i had declared an another ArrayList (sub) to keep all Integer values.
I had used ArrayList data structure because of length of the List will be changing the
run time.
Good Luck !!!
I created a method that puts the read numbers into a NumberArray and in total 2 NumberArrays are created per input file. I have created an array of the object NumberRow on the line I marked with "!!!!". I put the read double into the array. However, when I read those arrays, numberRow[0] is not correct; all the values belonging in numberRow[1] are in there, and the values in numberRow[1] are correct. There is probably a simple solution, but I really don't see what is going wrong here.
Unit[] unitArray = new Unit[dataset.numberOfRecords];
double[] emptyDoubleArray = new double[dataset.numberOfRecords];
for(int x = 0; x<dataset.numberOfVariables; x++){
numberRow[x] = new NumberRow(emptyDoubleArray);
}
for(int i = 0; i<dataset.numberOfRecords; i++){
String label = in.next();
double[] elementsPerUnit = new double[dataset.numberOfVariables];
for(int k = 0; k<dataset.numberOfVariables; k++){
double misc = in.nextDouble();
!!!!! numberRow[k].NumberArray[i] = misc;
elementsPerUnit[k] = misc;
}
unit = new Unit(label, elementsPerUnit);
unitArray[i] = unit;
}
unitRow = new UnitRow(unitArray);
out.print(Arrays.toString(numberRow[0].NumberArray));
}
Arrays are objects in Java. That is, they are not copied and passed by value (like int, etc), they are passed by reference (like Object, String...)
If you create an array with new and pass it to two objects, there is still only one array (you only used new once, think about it this way). When one object edits the array, the single copy of the array, having been edited, 's edits are seen by the other object.
The solution is, create a new array if it should be distinct from all other arrays.
EDIT: You create one array here (note the new)
double[] emptyDoubleArray = new double[dataset.numberOfRecords];
this one array is passed to all NumberRows (note, no new)
numberRow[x] = new NumberRow(emptyDoubleArray);
therefore if I edit any NumberRow's array it is seen in all NumberRows.
I need to create an Arraylist in a while loop with a name based on variables also in the loop. Here's what I have:
while(myScanner.hasNextInt()){
int truster = myScanner.nextInt();
int trustee = myScanner.nextInt();
int i = 1;
String j = Integer.toString(i);
String listname = truster + j;
if(listname.isEmpty()) {
ArrayList listname = new ArrayList();
} else {}
listname.add(truster);
i++;
}
The variable truster will show up more than once while being scanned, so the if statement is attempting to check if the arraylist already exists. I think I might have done that out of order, though.
Thanks for your help!
Store the ArrayLists in a Map:
Map<String, List<String> listMap = new HashMap<String,List<String>>();
while (myScanner.hasNextInt()){
// Stuff
List<String> list = new ArrayList<String>();
list.add(truster);
listMap.put(listname, list);
}
Note the use of generics (the bits in <>) to define the type of Object the List and Map can contain.
You can access the values stored in the Map using listMap.get(listname);
If I understand you correctly, create a list of lists or, better yet, create a map in which the key is the dynamic name you want and the value is the newly created list. Wrap this in another method and call it like createNewList("name").
Really not sure what you mean at all but you have some serious fundamental flaws with your code so I'll address those.
//We can define variables outside a while loop
//and use those inside the loop so lets do that
Map trusterMap = new HashMap<String,ArrayList<String>>();
//i is not a "good" variable name,
//since it doesn't explain it's purpose
Int count = 0;
while(myScanner.hasNextInt()) {
//Get the truster and trustee
Int truster = myScanner.nextInt();
Int trustee = myScanner.nextInt();
//Originally you had:
// String listname = truster + i;
//I assume you meant something else here
//since the listname variable is already used
//Add the truster concated with the count to the array
//Note: when using + if the left element is a string
//then the right element will get autoboxed to a string
//Having read your comments using a HashMap is the best way to do this.
ArrayList<String> listname = new ArrayList<String>();
listname.add(truster);
trusterMap.put(truster + count, listname);
i++;
}
Further, you are storing in myScanner a stream of Ints that will get fed in to the array, but which each have very different meanings (truster and trustee). Are you trying to read these in from a file, or user input? There are better ways of handling this and if you comment below with what you mean I'll update with a suggested solution.