Add same object to multiple arraylists - java

I'm working on a game and noticed that adding an object to two arraylists and then updating one of them doesn't update the other. Is it possible to solve this?
I have a list of all tiles which is looped though when rendering. But I also want a list of slots(extends Tile) in my inventory class instead of looping though all game tiles to get the inventory slots.
I have two lists: Game.tiles and Inventory.slots
This is where I add slots (Inventory class):
for(int i = 0; i< 16; i++){
Slot slot = new Slot();
Game.tiles.add(slot);
slots.add(slot);
}
And this is where I modify slots (Inventory class):
for(int i = 0; i< 16; i++){
slots.get(i).visable = false;
}
The problem is that the data updates for the slot in the slots list but not for the same slot in the Game.tiles list.
Full inventory class: http://pastebin.com/KS5BNB3F

When you add an object to two different ArrayList, you are actually adding only references to the object. So if you modify the object, it will reflect in both the lists at the same time. See the following code snippet:
public class Clazz{
private Integer d = 0;
public static void main(String[] args) throws Exception {
Clazz obj = new Clazz();
List<Clazz> list1 = new ArrayList<Clazz>();
List<Clazz> list2 = new ArrayList<Clazz>();
list1.add(obj);
list2.add(obj);
obj.d = 15;
System.out.println(list1.get(0).d); //prints 15
System.out.println(list2.get(0).d); //prints 15
}
}

Create an object instance, add it to both arrays. Then those arrays will have the same references. This means that updating your object would result in it updated in both arrays.

Related

How do I store user-entered names in array to be called in a later method? I can't ask for the number of names before hand, but know max [duplicate]

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.

Combining a static array with a dynamic ArrayList

I want to combine a static array (such as int[]) with a dynamic array such as ArrayList<String>
For example, I know the count of houses: 10 (fixed), but I don't know the count of humans who live in a house. This count will also change dynamically, like a List.
Is there any option to create a datatype which can fulfill both criteria?
An ArrayList is a dynamicly sized data structure backed by an array. It sounds to me like you could have an array of House where each House has a List<Human> field.
House[] homes = new House[10];
and a class like
class House {
private List<Human> people = new ArrayList<>();
public List<Human> getPeople() {
return people;
}
}
then to get the total count of people in those homes you might use something like
int count = 0;
for (House h : homes) {
count += h.getPeople().size();
}
This works for me:
ArrayList<String>[] house = new ArrayList[15];
for (int x = 0; x < house.length; x++) {
house[x] = new ArrayList<String>();
}
house[0].add("Pete");
house[0].add("Marta");
house[1].add("Dave");
System.out.println(house[0]);
System.out.println(house[1]);
out:
[Pete, Marta]
[Dave]
..i used this Create an Array of Arraylists

Java Creating Objects at Runtime in a For Loop

I'm trying to create objects within a for loop at runtime. Here is the (incorrect) code:
for(int i=1;i<max;i++){
Object object(i);
}
I'd like it to create max number of Object objects with names object1, object2, etc. Is there any way to do this? I have been unable to find anything elsewhere online. Thanks for your help!
You want to use a data structure to store a sequence of objects. For example, an array could do this:
Fruit banana[] = new Fruit[10];
for (int i = 0; i < 10; i++){
banana[i] = new Fruit();
}
This creates 10 objects of type Fruit in the banana array, I can access them by calling banana[0] through banana[9]
You could use an array to create multiple objects.
public void method(int max) {
Object[] object = new Object[max];
for (int i = 0; i < max; i++) {
object[i] = new Object();
}
}

How to move data from multiple Arraylist to multiple Arrays (in Java)

I have 3 arraylist each have size = 3 and 3 arrays also have length = 3 of each. I want to copy data from arraylists to arrays in following way but using any loop (i.e for OR for each).
myArray1[1] = arraylist1.get(1);
myArray1[2] = arraylist2.get(1);
myArray1[3] = arraylist3.get(1);
I have done it manually one by one without using any loop, but code appears to be massive because in future I'm sure that number of my arraylists and arrays will increase up to 15.
I want to copy the data from arraylists to arrays as shown in the image but using the loops not manually one by one?
How about this?
List<Integer> arraylist0 = Arrays.asList(2,4,3);
List<Integer> arraylist1 = Arrays.asList(2,5,7);
List<Integer> arraylist2 = Arrays.asList(6,3,7);
List<List<Integer>> arraylistList = Arrays.asList(arraylist0, arraylist1, arraylist2);
int size = 3;
int[] myArray0 = new int[size];
int[] myArray1 = new int[size];
int[] myArray2 = new int[size];
int[][] myBigArray = new int[][] {myArray0, myArray1, myArray2};
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
myBigArray[i][j] = arraylistList.get(j).get(i);
}
}
To explain, since we want to be able to work with an arbitrary size (3, 15, or more), we are dealing with 2-dimensional data.
We are also dealing with array and List, which are slightly different in their use.
The input to your problem is List<Integer>, and so we make a List<List<Integer>> in order to deal with all the input data easily.
Similarly, the output will be arrays, so we make a 2-dimensional array (int[][]) in order to write the data easily.
Then it's simply a matter of iterating over the data in 2 nested for loops. Notice that this line reverses the order of i and j in order to splice the data the way you intend.
myBigArray[i][j] = arraylistList.get(j).get(i);
And then you can print your answer like this:
System.out.println(Arrays.toString(myArray0));
System.out.println(Arrays.toString(myArray1));
System.out.println(Arrays.toString(myArray2));
You need to have two additional structures:
int[][] destination = new int [][] {myArray1, myArray2,myArray3 }
List<Integer>[] source;
source = new List<Integer>[] {arraylist1,arraylist2,arraylist3}
myArray1[1] = arraylist1.get(1);
myArray1[2] = arraylist2.get(1);
myArray1[3] = arraylist3.get(1);
for (int i=0;i<destination.length;i++) {
for (int j=0;j<source.length;j++) {
destination[i][j] = source[j].get(i);
}
}
If you cannot find a ready made API or function for this, I would suggest trivializing the conversion from List to Array using the List.toArray() method and focus on converting/transforming the given set of lists to a another bunch of lists which contain the desired output. Following is a code sample which I would think achieves this. It does assume the input lists are NOT of fixed/same sizes. Assuming this would only make the logic easier.
On return of this function, all you need to do is to iterate over the TreeMap and convert the values to arrays using List.toArray().
public static TreeMap<Integer, List<Integer>> transorm(
List<Integer>... lists) {
// Return a blank TreeMap if not input. TreeMap explanation below.
if (lists == null || lists.length == 0)
return new TreeMap<>();
// Get Iterators for the input lists
List<Iterator<Integer>> iterators = new ArrayList<>();
for (List<Integer> list : lists) {
iterators.add(list.iterator());
}
// Initialize Return. We return a TreeMap, where the key indicates which
// position's integer values are present in the list which is the value
// of this key. Converting the lists to arrays is trivial using the
// List.toArray() method.
TreeMap<Integer, List<Integer>> transformedLists = new TreeMap<>();
// Variable maintaining the position for which values are being
// collected. See below.
int currPosition = 0;
// Variable which keeps track of the index of the iterator currently
// driving the iteration and the driving iterator.
int driverItrIndex = 0;
Iterator<Integer> driverItr = lists[driverItrIndex].iterator();
// Actual code that does the transformation.
while (driverItrIndex < iterators.size()) {
// Move to next driving iterator
if (!driverItr.hasNext()) {
driverItrIndex++;
driverItr = iterators.get(driverItrIndex);
continue;
}
// Construct Transformed List
ArrayList<Integer> transformedList = new ArrayList<>();
for (Iterator<Integer> iterator : iterators) {
if (iterator.hasNext()) {
transformedList.add(iterator.next());
}
}
// Add to return
transformedLists.put(currPosition, transformedList);
}
// Return Value
return transformedLists;
}

Can you create an array of linked lists in Java?

Is it possible to create an array of linked lists? Or an arraylist of linked lists? I've been searching everywhere and seem to be getting contradicting answers. I've seen "no" answers that state that it can't be done because you can't make an array of things that can be dereferenced. I've seen "yes" answers that state it can be done and they end there.
Thanks in advance.
If I understand you right, you basicly want to make a 2D Array, but with the second half being a linked list.
import java.util.ArrayList;
import java.util.LinkedList;
public class Test
{
public static void main(String[] args)
{
LinkedList one = new LinkedList();
LinkedList two = new LinkedList();
LinkedList three = new LinkedList();
ArrayList<LinkedList> array = new ArrayList<LinkedList>();
array.add(one);
array.add(two);
array.add(three);
// .. do stuff
}
}
Java doesn't care what the Objects in Arrays or Lists are, so there's nothing against putting another Array or List in.
The worst way: creating an array of raw List:
List[] lstString = new List[10];
for(int i = 0; i < lstString.length; i++) {
lstString[i] = new LinkedList<String>();
lstString[i].add(Integer.toString(i));
}
for(int i = 0; i < lstString.length; i++) {
for(Iterator it = lstString[i].iterator(); it.hasNext(); ) {
System.out.println(it.next());
}
}
A slightly better way: use a wrapper class that holds your List and create an array of it:
public class Holder {
List list = new LinkedList();
}
//...
Holder[] holders = new Holder[10];
for(int i = 0; i < holders; i++) {
holders[i] = new Holder();
}
Better approach: use a List<List<Data>>:
List<List<Data>> lstOfListOfData = new ArrayList<List<Data>>();
for(int i = 0; i < 10; i++) {
lstOfListOfData.add(new LinkedList<Data>());
}
I've seen "no" answers that state that it can't be done because you can't make an array of things that can be dereferenced
Doesn't matter if the array's member value is null, if you still can "access" that member, and instantiate it, it's not dereferenced.
So yes, you can.

Categories