Java - Reading from an ArrayList from another class - java

We've not covered ArrayLists only Arrays and 2D arrays. What I need to do is be able to read from an ArrayList from another class. The main aim is to read from them in a for loop and use the values stored in them to display items. However, I have made this quick program to test it out and keep getting this error
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at Main.Main(Main.java:14)
Here is my code
import java.util.ArrayList;
public class Main
{
public static void Main()
{
System.out.println("Test");
ArrayList <Objects> xcoords = new ArrayList<Objects>();
for( int x = 1 ; x < xcoords.size() ; x++ )
{
System.out.println(xcoords.get(x));
}
}
}
And then the class where the ArrayList is
import java.util.ArrayList;
public class Objects
{
public void xco()
{
ArrayList xcoords = new ArrayList();
//X coords
//Destroyable
xcoords.add(5);
xcoords.add(25);
xcoords.add(5);
xcoords.add(5);
xcoords.add(25);
xcoords.add(5);
//Static Walls
xcoords.add(600);
xcoords.add(400);
xcoords.add(600);
}
}
If someone can point me in the correct direction it would be so valuable. I've tried to debug however I can get anything helpful.
Thanks in advance.

Strictly speaking, the exception is due to indexing location 1 of an ArrayList with 0 elements. Notice where you start you for loop index variable x. But consider this line:
ArrayList <Objects> xcoords = new ArrayList<Objects>();
xcoords points to a new, empty ArrayList, not the one you created in class Objects. To get that ArrayList, change the method xco like
public ArrayList<Integer> xco() { // make sure to parameterize the ArrayList
ArrayList<Integer> xcoords = new ArrayList<Integer>();
// .. add all the elements ..
return xcoords;
}
then, in your main method
public static void main(String [] args) { // add correct arguments
//..
ArrayList <Integer> xcoords = (new Objects()).xco();
for( int x = 0 ; x < xcoords.size() ; x++ ) { // start from index 0
System.out.println(xcoords.get(x));
}
}

Here you're simply creating two completely unrelated lists. Either have the array list be a property of the Objects class and retrieve it through an instance method, or return it from an instance or static method, or make the property static. IMO the first two are preferable in most situations.
public class Objects {
public static List<Integer> getXcoords() {
List<Integer> xcoords = new ArrayList<Integer>();
// Your same code, but adding:
return xoords;
}
}
Then to use it:
import java.util.ArrayList;
public class Main {
// Note the lower-case "main" here. You want that.
public static void main() {
List<Integer> xcoords = Objects.getXcoords();
// etc.
Also, your List should be of Integer, not of Objects, which would create a collection holding instances of Objects. You may want to take a step back and relate lists to arrays in a better way--you wouldn't create an array of Objects, would you? No, you'd have an array of int or Integer.
Also, there's Arrays.asList.

You have an IndexOutOfBoundsException which means that you are trying to access an element in an array which is not existing.
But in your code posted here you are not accessing an array at all (your for loop will not execute once because the list is empty), which means that your exception is thrown somewhere else.
But also your code doesn't make any sense. I refactored it for you while staying as close to your code as possible, so you can see how it could work:
public static void main(String[] args){
Objects myObjects = new Objects();
ArrayList<Integer> listFromMyObjects = myObjects.getList();
for( int x = 0 ; x < listFromMyObjects.size() ; x++ )
{
System.out.println(listFromMyObjects.get(x));
}
}
public class Objects
{
private ArrayList<Integer> myList;
public Objects(){
myList = new ArrayList<Integer>();
myList.add(5);
myList.add(25);
myList.add(5);
myList.add(5);
myList.add(25);
myList.add(5);
myList.add(600);
myList.add(400);
myList.add(600);
}
public ArrayList<Integer> getList(){
return myList;
}
}

Related

printing all subsequences of an array using recursion in JAVA

The following code for above requirement. However I am not getting proper output. There is problem with input list that I am passing in recursion
import java.util.ArrayList;
import java.util.Collections;
public class abc
{
public static void m(ArrayList<Integer> op, ArrayList<Integer> ip) {
if(ip.size()==0) {
System.out.println(op);
return;
}
ArrayList<Integer> l1=new ArrayList<Integer>();
ArrayList<Integer> l2=new ArrayList<Integer>();
l1.addAll(op);
l2.addAll(op);
l1.add(ip.get(0));
ip.remove(0);
m(l2,ip);
m(l1,ip);
}
public static void main(String[] args) {
Integer [] z = {1,3,2};
ArrayList<Integer> ip=new ArrayList<Integer>();
Collections.addAll(ip, z);
ArrayList<Integer> op=new ArrayList<Integer>();
m(op,ip);
}
}
The problem is not, like you said in your comment, that the list ip keeps elements of the previous function call. The problem is that you don't create a new arraylist as ip parameter for the next function call, meaning, as it is call by reference, that you remove the elements of one function call already in the other function call. You can fix this by just creating a new array list for the new function call, like you already to for op. However you could also use this:
m(l2,new ArrayList<>(ip));
m(l1,new ArrayList<>(ip));
so you don't have to use an extra addAll() ;)

Error : Type mismatch: cannot convert from List<Integer> to ArrayList<Integer>

package set01;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class DFTList {
static List<Integer>[] list;
static boolean[] visited;
public DFTList(int nodes) {
list = new ArrayList[nodes];
visited = new boolean[nodes];
for(int i=0;i<nodes;i++) {
list[i] = new ArrayList<>();
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter no. of nodes : ");
int nodes = scan.nextInt();
DFTList obj = new DFTList(nodes);
System.out.println("Enter no.of vertex : ");
int vertex = scan.nextInt();
for(int i=0;i<vertex;i++) {
int v1 = scan.nextInt();
int v2 = scan.nextInt();
list[v1].add(v2);
list[v2].add(v1);
}
solve(0);
}
public static void solve(int a) {
visited[a] = true;
ArrayList<Integer> l = list[a];
}
}
In the above code snippet, At the DFTList constructor, I have inserted ArrayList object at all the indices of the array. But when I try to retrieve the same object at the solve method and store it under the same reference, I encountered an error stating that "Type mismatch: cannot convert from List to ArrayList". Why does this error occur?
The list variable is a List<Integer>[], which means that any type of List (ArrayList, LinkedList, etc.) could be stored in it. When retrieving an element from this list, all the Java compiler knows is that it's some type of List; it doesn't know the specific type of List (even though you as the programmer know that you're only storing ArrayList items in the array). Therefore, ArrayList<Integer> l = list[a] is a compilation failure because the compiler can't guarantee that the element retrieved from the array is an ArrayList and not a different List type.
There are a few ways to address this issue. Assuming you wanted to keep list as an array, the most idiomatic approach would be to change its type to List<Integer>[] instead of ArrayList<Integer>[]. Since you are not using any methods or other API specific to ArrayList, the List interface is a better choice for this type.
public static void solve(int a) {
visited[a] = true;
List<Integer> l = list[a];
}
Another, less idiomatic approach would be to change the type of the list variable from List<Integer>[] to ArrayList<Integer>[]. This change would cause your variable assignment to work as already written.
public class DFTList {
static ArrayList<Integer>[] list;
...
}
The final approach you could use when you have an array of the interface type (List<Integer> in this case) would be to cast the element to the concrete type when storing it to the variable. This is basically telling the compiler that you as the developer know the element is of that subtype, so even though it cannot guarantee the assignment, it will allow it to happen. This approach defers the type checking — ensuring the List is the ArrayList subtype — until the code is actually run (at runtime). If the stored element is a subtype other than ArrayList when the code is run (e.g. if it's a LinkedList), then Java will throw a ClassCastException since the assignment to ArrayList cannot happen.
Casting like this is not ideal, as it removes guarantees by the compiler that all types being used are guaranteed to be valid at runtime. However, there are times where it is necessary and appropriate.
public static void solve(int a) {
visited[a] = true;
ArrayList<Integer> l = (ArrayList<Integer>) list[a];
}
list is declared as a List<Integer>[] (read: an array of Lists of Integers). The fact that the value in each element is actually an ArrayList is inconsequential - as far as the compiler is concerned, every element is a List.
You could either explicitly downcast the array access:
ArrayList<Integer> l = (ArrayList<Integer>)list[a];
Or, more idiomatically, if you aren't relying on any specific method ArrayList has that isn't present in the List interface, you could declare l as a List<Integer>:
List<Integer> l = list[a];
you are mixing C++ with Java!!
check the following reproducable code:
public class DFTList {
static List<Integer>[] list;
static boolean[] visited;
public DFTList(int nodes) {
list = new ArrayList[nodes];
visited = new boolean[nodes];
for(int i=0;i<nodes;i++) {
list[i] = new ArrayList<>();
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter no. of nodes : ");
int nodes = scan.nextInt();
DFTList obj = new DFTList(nodes);
System.out.println("Enter no.of vertex : ");
int vertex = scan.nextInt();
for(int i=0;i<vertex;i++) {
int v1 = scan.nextInt();
int v2 = scan.nextInt();
list[v1].add(v2);
list[v2].add(v1);
}
solve(0);
}
public static void solve(int a) {
visited[a] = true;
List<Integer> l = list[a];
}
}
Note 0
there is no pointer like concept in java therefore following snippet gives you compile time error:
* list[i] = new ArrayList<>();
Note 1
you are assigning List interface to l type therefore use below syntax.
List<Integer> l = list[a];

Im having trouble understanding how to pass an array to a method, and return an array list

I am having trouble finishing this intro to Java assignment. My goal is pass nums[] into the method array() and then have array() return an ArrayList containing all of the "freezing" temps found in nums[]. Any help would be appreciated
import java.util.ArrayList;
import java.util.Arrays;
public class Program73 {
public static int[] array(int[] array) {
return array;
}
public static void main(String[] args) {
int nums[] = new int[14];
System.out.println("The temperatures in the last two weeks...: ");
for(int i = 0; i < nums.length; i++) {
nums[i] = (int)(Math.random() * 11) + 50;
System.out.print(nums[i] + " ");
}
System.out.println("These 5 were below freezing...:");
}
}
An ArrayList or more generally a List is nothing more than a class that implements the List interface to facilitate manipulating collections of data.
In the case of ArrayList it uses a regular array (e.g. Object[]) to store the data while providing various methods to navigate and manipulate the list. Some specific differences from the users point of view between an ArrayList and an array are.
ArrayLists grow dynamically and do not need to be pre-allocated.
You can delete (remove) an element anywhere from an ArrayList.
You can see if the ArrayList contains a specific element.
You can easily sort an ArrayList
many other examples also exist.
None of the above capabilities are free. They are simply methods implemented in a class, acting as a front-end to an array to make writing code easier.
int [] array = new int[10];
// fill the array with ints
List<Integer> list = toList(array);
public List<Integer> toList(int[] a) {
// do something with a
// like print them out.
List<Integer> list = new ArrayList<>();
for (int i : a) {
list.add(i);
}
return list;
}

Strange Problems with Strings in Java

I am new to JAVA and found some of its concepts very irritating and no matter how hard I try I can not find suitable explanation for this behavior...of course there are wor around for these problems but still I want to know am I missing something very simple here or JAVA is like this???
I have a string array in one of my class A and I want it to be filled through a method of another class B...so I create an object of class B into A and call the method B.xyz and equate it to the string arra but BOOM I can't do it....java throws a nullpointer exception..........I dont know why...
.
public class B{
public void xyz() {
String[] mystrings=new String[70];
for(int i=0;i<5;i++)
mystrings[i]=value;
return mystrings;
}
}
public class A {
public void abc() {
B b=new B();
String[] StringList;
StringList=b.xyz();
System.out.println(StringList.length);
}
}
I have a similar code fragment now sadly the length of the StrinList becomes 70....if I want to print all the strings of this array I dont have any other way....remember even though the size of mystring is 70 in class B only 5 of its components are properly initialized........SO considering I am in class A and have no way to find out how many times did the for loop in B executed......how do I accurately loop through all the elements of StringList in A.........
PS: There are workarounds to solve this problem but I wanted to know why this happens,i.e, why the length attribute doesn't change according to the components initialized??
If you only need an array of length 5 then only initialize it as that size, e.g.:
public String[] xyz(String value) {
String[] mystrings = new String[5];
for (int i = 0; i < mystrings.length; i++) {
mystrings[i] = value;
}
return mystrings;
}
If you want an array that you can expand you should consider using ArrayList instead. E.g.:
public List<String> abc(String value) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 5; i++) {
list.add(value);
}
return list;
}
Then you can get its size, add to it and print the elements like this:
List<String> list = abc("foo");
System.out.println(list.size());
list.add("bar");
for (String value : list) {
System.out.println(value);
}
Hope that helps.
You declared xyz as a method with return type void in class B. Presumably you want a signature that returns a string array, public String[] xyz()
Also you didn't declare the array correctly in B, the correct declaration is:
String[] myStrings = new String[70];
-- Dan
String[] mystrings = new String[5];
I suggest you look at using List like ArrayList as this wraps arrays to make them easier to use.
String[] mystrings[70];
This creates an array or arrays. There are two []
I suggest you try instead.
String[] mystrings = new String[5];

Java dynamic array sizes?

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.

Categories

Resources