Combining a static array with a dynamic ArrayList - java

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

Related

Add same object to multiple arraylists

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.

arraylist to array unique order

So I'm trying to go through an arraylist of objects that all have a certain strength value and depending on their strength value, they go into the bigger 2d array based on that. So if their strength value is 0 then they go in the 0th array of the bigger one and this is what my code looks like so far
private ArrayList<Battleable> arr;
public BattleDeck() {
arr = new ArrayList<Battleable>();
for (Battleable creature: arr){
arr.add(creature);
}
}
public Battleable[][] export2Darray() {
//returns a two-dimensional ragged array where each row
// contains a deep copy of all of the Battleable objects
// in the BattleStack with the corresponding Level value
Battleable[][] retVal = new Battleable[10][];
int k = 0;
for (int i = 0; i<arr.size(); i++){
int levelOfObj = arr.get(i).getLevel();
if(levelOfObj == k) {
//insert it into retVal[0][0]
}
}
}
return retVal;
}
and I was wondering how I would do that? How do i syntax-tically say "get the obj that has strength 0 and put it in position 0 0 of my 2d array
A solution using Java 8 streams:
// group Battleables ArrayList by strength
Map<Integer, List<Battleable>> map =
arr.stream().collect(Collectors.groupingBy(Battleable::getStrength));
The result is a Map containing the Battleables as Lists with their strength as their key.
If you need the result as a jagged 2D array, sort the entries like this:
final Battleable[][] arrays = new Battleable[10][];
map.entrySet().forEach(entry -> {
arrays[entry.getKey()] = entry.getValue().toArray(new Battleable[entry.getValue().size()]);
});
Since arrays are of fixed size in Java, there is no clean way to add items to an array. You can resize the array each time by creating a new array each time, one larger than the last, and copying the data from the old array to the new array, but that would be messy and you would be reinventing a wheel called ArrayList. Modus Tollens has a good answer, but it uses some slightly advanced Java 8 concepts. Here's one way to write it without them:
public Battleable[][] export2Darray() {
Battleable[][] retVal = new Battleable[10][];
// create a map that will hold the items, arranged by level
Map<Integer, List<Battleable>> byLevel = new HashMap<>();
for (int i = 0; i < 10; i++) {
// initialize all levels with empty lists
byLevel.put(i, new ArrayList<>());
}
for (Battleable battleable : arr) {
int level = battleable.getLevel();
// get the list for this level and add to it
byLevel.get(level).add(battleable);
}
// Now we have a map from levels to lists of battleables;
// we need to turn each list into an array in our retVal
for (int level = 0; level < 10; level++) {
// get each list, convert it toArray and assign to slot in retVal
retVal[level] = byLevel.get(level).toArray(new Battleable[0]);
}
return retVal;
}
Here's a solution using ArrayLists, I am creating an ArrayList which will be referenced by strength, then inside of this I have another ArrayListwhich will have all of the Battleable objects of that strength level.
public ArrayList<ArrayList<Battleable>> exportBattleable() {
ArrayList<ArrayList<Battleable>> retVal = new ArrayList<ArrayList<Battleable>>();
for (int i = 0; i < arr.size(); i++){
retVal.get(arr.getLevel()).add(arr.get(i));
}
return retVal;
}
Now if you want to print all Battleable objects of strength = 3, you would do:
ArrayList<Battleable> strength3 = retVal.get(3);
for(Battleable battleable : strength3) {
System.out.println(battleable.toString());
}
This way you don't have to worry about re-sizing your arrays depending on how many Battleable objects you are adding in, same with strength levels, if you decide that instead of using strength levels from 0-9 that you wanted to use 0-20 you already have the ability to scale up or down.

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;
}

Java, how to adjust second dimension of 2 dimensional array?

In my application I need to have a 2 dimensional array. If I define it fix it works fine, like this:
static final String arrGroupelements[] = {"India", "Australia", "England", "South Africa"};
static final String arrChildelements[][] = { {"Sachin Tendulkar", "Raina", "Dhoni", "Yuvi" },
{"Ponting", "Adam Gilchrist", "Michael Clarke"},
{"Andrew Strauss", "kevin Peterson", "Nasser Hussain"},
{"Graeme Smith", "AB de villiers", "Jacques Kallis"} };
However, in my code I have two lists. the first is list of recipe name that i can get it.
LinkedList<String> recipeList = dbShoppingHandler.getAllRecipeNames();
String arrGroupelements[] = new String[recipeList.size()];
for(int i=0; i<recipeList.size(); i++) {
arrGroupelements[i] = recipeList.get(i);
}
My second list is list of ingredients. In order to get list of ingredients i need to set recipe name and then i can get the list. However, i don't know how put this list as second dimension. my code is like this:
String arrChildelements[][] = new String[recipeList.size()][20];
for(int i=0; i<recipeList.size(); i++) {
LinkedList<String> ingredient = dbShoppingHandler.getIngredientsOfRecipeName(recipeList.get(i));
for(int j=0; j<ingredient.size(); j++) {
arrChildelements[i][j] = ingredient.get(j);
}
}
Bad thing is, i need to set a number (in my case 20) for second dimension. If i do like this for lists that have 5 items i will have 15 " " elements and those have more than 20 items the code ignore them.
First dimension is fix but i need to adjust second dimension based on number of ingredients.
any suggestion are appreciated. thanks.
How about assigning an array in the desired sise:
String arrChildelements[][] = new String[recipeList.size()][];
// not mentioning second dimension size ^^
for(int i=0; i<recipeList.size(); i++) {
LinkedList<String> ingredient = dbShoppingHandler.getIngredientsOfRecipeName(recipeList.get(i));
arrChildelements[i] = String[ingredient.size()];
// assigning new array here ^^
for(int j=0; j<ingredient.size(); j++) {
arrChildelements[i][j] = ingredient.get(j);
}
}
I suggest not to use 2D arrays for dynamic structures. Arrays are immutable, so you have to copy them, create gaps and move elements around. The standard Java library doesn't offer many useful methods to do that.
Instead, use a list of lists:
List<List<String>> data = new ArrayList<List<String>>();
Lists have many useful methods to append elements, insert and remove them and they will make you life much easier.
The simplest way to to not assume you know the length in advance.
String[][] arrChildelements[] = new String[recipeList.size()][];
for(int i=0; i<recipeList.size(); i++) {
List<String> ingredient = dbShoppingHandler.getIngredientsOfRecipeName(recipeList.get(i));
arrChildelements[i] = ingredient.toArray(new String[0]);
}

Categories