array of objects proper way of use? - java

What I have is
public static LinkedList<Mp3> musicList;
...
if (musicList == null) {
musicList = new LinkedList<Mp3>();
}//create... this works
but if I have like 5 or more lists how can I do something like this:
Object[] ob = new Object[]{musicList,musicList2,...,musicList10};
for (int i = 0; i < ob.length; i++){
if (ob[i] == null) ob[i] = new LinkedList<Mp3>();
}
If I put it in first way it's working; how can I put it in like in second snippet?

Avoid mixing arrays and generics.
Instead, consider this:
List<List<Mp3>> listsList = new ArrayList<List<Mp3>>();
listsList.add(new LinkedList<Mp3>());

Changing the references in the array will not change the original references used to create the array.
The references in the array are a copy of what was in the initialization.
What you should do is get rid of the musicListN variables and only have an array, or better yet use a List.
List<List<Mp3>> musicLists = new ArrayList<List<Mp3>>(LIST_COUNT);
for (int i = 0; i < LIST_COUNT; i++) {
musicLists.add(new LinkedList<Mp3>());
}
Then use musicLists.get() to everywhere you would have used the older variables.

If you really want to do one line object list initialization, look at this Q. Initialization of an ArrayList in one line

Related

I never figure out the correct way to create an 2D ArrayList

List<ArrayList<Planet>> NAME = new ArrayList<ArrayList<Planet>>(N);
List<List<Planet>> NAME = new ArrayList<ArrayList<Planet>>(N);
ArrayList<ArrayList<Planet>> NAME = new ArrayList<ArrayList<Planet>>(N);
I can't tell what's the difference of these three expressions. I realized later that maybe List is for declaration because its an interface while ArrayList could be used for initiation, as it is a class. I took the first syntax in my project and find
found : java.util.ArrayList>
required: java.util.ArrayList>
List<List<Planet>> Name = new ArrayList<ArrayList<Planet>>(N);
I have added at the header.
import java.util.ArrayList;
import java.util.List;
In another place, while I am adding Planet Object into the ArrayList:
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == j) continue;
NAME[i].add(planets[j]);
}
}
The compiler reports,
array required, but java.util.ArrayList> found
planetsForNetForceSetting[i].add(planets[j]);
Could anybody tell me the reason for this?
You are trying to retrieve data from given position of a List like an Array here: NAME[i].add(planets[j]);, what cannot be done.
To get data from an ArrayList you must use get(int) method. In thi way: NAME.get(i) instead NAME[i].
Then, your method must be
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == j) continue;
NAME.get(i).add(planets[j]);
}
}
About difference of three expressions, and why use interface to declare List<Object> list = new ArrayList<Object> instead of the class itself, look at this question.
First List<T> is a java interface parametrized by type T. ArrayList<T> is specific implementation of interface List<T>. So you may assign List<Integer> list = new ArrayList<Integer>(); This way variable list will have type List<Integer> which will hide specific implementation ArrayList<T>.
Then following lines:
List<ArrayList<Planet>> planetsList = new ArrayList<ArrayList<Planet>>();
creates variable planetsList of type List<ArrayList<Planet>> which is list of array lists. Where actual outer lists implementation is ArrayList<ArrayList<Planet>>.
List<List<Planet>> planetsList2 = new ArrayList<ArrayList<Planet>>();
Will not compile, since you cannot assign ArrayList<ArrayList<Planet>> to List<List<Planet>> Refer to this question to more deep explanation why Why can't you have a "List<List<String>>" in Java?
ArrayList<ArrayList<Planet>> planetsList3 = new ArrayList<ArrayList<Planet>>();
Will create variable planetsList3 with type ArrayList<ArrayList<Planet>>.
You need to import both java.util.List and java.util.ArrayListtypes since you are directly referencing them in your code.
And finally. You cannot assign item to list's index by array indexing syntax items[index]=item; since List<ItemType> items; is an interface not an array. These are totally different things in java.
Out of your 3 expressions, in same order as you mentioned, 2nd one is the most generic one, then 1st and then 3rd.
Which means that when you use List<Planet> listObj then you can use listObj to point to any implementation of List interface. While when you do ArrayList<Planet> listObj then you can use listObj to point to only an object of type ArrayList
Whether 1 dimensional or N dimensional, this hold true.
A more generic type and preferred one would be use of List<Object> listObj, which means that you can use listObj to point to any implementation of List interface, ALSO you in the list you can put any object. When you use List<Planet> listObj then you can only put Planet objects.
For your compile problem, your code is not sufficient to figure out root cause because I cannot see whats planetsForNetForceSetting, but just make sure that you are putting right objects in right place. Like I explained above.
Hope this helps!!!

Array of classes which create instances

having Obj class which in his constructor has System.out.println("Hello world!") ;
I create an array of this class using - Obj[] objArray = new Obj[10] ; and nothing printed , means - no instance of Obj has been called . Is there any way to create such array ,but with instances , beyond create them in for loop ?
Well, since you want to know a way apart from using a for loop, you can do this: -
Obj[] objArray = {new Obj(), new Obj(), new Obj()};
What happens here is, you are initializing your array reference directly with array elements.
Now the type of actual array object is inferred from type of array reference on the LHS.
So, with that declaration, an array of size 3 (in the above case) is created, with each index in the array initialized with the instance of Obj class in the given order.
A better way that I would suggest is to use an ArrayList, in which case, you have double-braces initialization to initialize your List without for loop. And plus with an added advantage that you can anytime add new elements to it. As it dynamically increasing array.
List<Object> list = new ArrayList<Object>() {
{
add(new Obj());
add(new Obj());
add(new Obj());
}
}; // Note the semi-colon here.
list.add(new Obj()); // Add another element here.
Answers so far are good and helpful. I'm here just to remind you about
Obj[] objArray = new Obj[10];
Arrays.fill(objArray, new Obj());
Though, this will only assign one reference (to a new Obj()) to all of the elements of array.
When you do Obj[] objArray = new Obj[10] ;
You only create an array of references to point to the actual 'Obj` object.
But in your case the actual Obj object is never created.
for (int i = 0; i < objArray.length; i++) {
objArray[i] = new Obj();
}
Doing above will print the desired.
Finally do System.out.println(Arrays.deepToString(objArray)) to print toString() of all the Obj
Obj[] objArray = new Obj[10] ; just creates an array capable of holding 10 Objs. To place Objs into the array you need to either use Rohit's approach or write a simple for loop to initialize the array entries one at a time:
for (int i = 0; i < 10; i++) {
objArray[i] = new Obj();
}
Or, without a for loop:
int i = 0;
while (i < 10) {
objArray[i] = new Obj();
i++;
}

How can I create an Array of ArrayLists?

I am wanting to create an array of arraylist like below:
ArrayList<Individual>[] group = new ArrayList<Individual>()[4];
But it's not compiling. How can I do this?
As per Oracle Documentation:
"You cannot create arrays of parameterized types"
Instead, you could do:
ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);
As suggested by Tom Hawting - tackline, it is even better to do:
List<List<Individual>> group = new ArrayList<List<Individual>>(4);
As the others have mentioned it's probably better to use another List to store the ArrayList in but if you have to use an array:
ArrayList<Individual>[] group = (ArrayList<Individual>[]) new ArrayList[4];
You will need to suppress the warning but it's safe in this case.
This works:
ArrayList<String>[] group = new ArrayList[4];
Though it will produce a warning that you may want to suppress.
You can create a class extending ArrayList
class IndividualList extends ArrayList<Individual> {
}
and then create the array
IndividualList[] group = new IndividualList[10];
You can create Array of ArrayList
List<Integer>[] outer = new List[number];
for (int i = 0; i < number; i++) {
outer[i] = new ArrayList<>();
}
This will be helpful in scenarios like this. You know the size of the outer one. But the size of inner ones varies. Here you can create an array of fixed length which contains size-varying Array lists. Hope this will be helpful for you.
In Java 8 and above you can do it in a much better way.
List<Integer>[] outer = new List[number];
Arrays.setAll(outer, element -> new ArrayList<>());
This works, array of ArrayList. Give it a try to understand how it works.
import java.util.*;
public class ArrayOfArrayList {
public static void main(String[] args) {
// Put the length of the array you need
ArrayList<String>[] group = new ArrayList[15];
for (int x = 0; x < group.length; x++) {
group[x] = new ArrayList<>();
}
//Add some thing to first array
group[0].add("Some");
group[0].add("Code");
//Add some thing to Secondarray
group[1].add("In here");
//Try to output 'em
System.out.println(group[0]);
System.out.println(group[1]);
}
}
Credits to Kelvincer for some of codes.
The problem with this situation is by using a arraylist you get a time complexity of o(n) for adding at a specific position. If you use an array you create a memory location by declaring your array therefore it is constant
You can't create array of generic type. Create List of ArrayLists :
List<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>();
or if you REALLY need array (WARNING: bad design!):
ArrayList[] group = new ArrayList[4];
Creation and initialization
Object[] yourArray = new Object[ARRAY_LENGTH];
Write access
yourArray[i]= someArrayList;
to access elements of internal ArrayList:
((ArrayList<YourType>) yourArray[i]).add(elementOfYourType); //or other method
Read access
to read array element i as an ArrayList use type casting:
someElement= (ArrayList<YourType>) yourArray[i];
for array element i: to read ArrayList element at index j
arrayListElement= ((ArrayList<YourType>) yourArray[i]).get(j);
List[] listArr = new ArrayList[4];
Above line gives warning , but it works (i.e it creates Array of ArrayList)
To declare an array of ArrayLists statically for, say, sprite positions as Points:
ArrayList<Point>[] positionList = new ArrayList[2];
public Main(---) {
positionList[0] = new ArrayList<Point>(); // Important, or you will get a NullPointerException at runtime
positionList[1] = new ArrayList<Point>();
}
dynamically:
ArrayList<Point>[] positionList;
int numberOfLists;
public Main(---) {
numberOfLists = 2;
positionList = new ArrayList[numberOfLists];
for(int i = 0; i < numberOfLists; i++) {
positionList[i] = new ArrayList<Point>();
}
}
Despite the cautions and some complex suggestions here, I have found an array of ArrayLists to be an elegant solution to represent related ArrayLists of the same type.
ArrayList<String>[] lists = (ArrayList<String>[])new ArrayList[10];
You can create like this
ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];
You have to create array of non generic type and then cast it into generic one.
ArrayList<Integer>[] graph = new ArrayList[numCourses]
It works.
I think I'm quite late but I ran into the same problem and had to create an array of arraylists as requested by my project in order to store objects of different subclasses in the same place and here is what I ended up doing:
ArrayList<?>[] items = new ArrayList[4];
ArrayList<Chocolate> choc = new ArrayList<>();
ArrayList<Chips> chips = new ArrayList<>();
ArrayList<Water> water = new ArrayList<>();
ArrayList<SoftDrink> sd = new ArrayList<>();
since each arraylist in the array would contain different objects (Chocolate , Chips , Water and SoftDrink )
--it is a project to simulate a vending machine--.
I then assigned each of the Arraylists to an index of the array:
items[0]=choc;
items[1]=chips;
items[2]=water;
items[3]=sd;
Hope that helps if anyone runs into a similar issue.
I find this easier to use...
static ArrayList<Individual> group[];
......
void initializeGroup(int size)
{
group=new ArrayList[size];
for(int i=0;i<size;i++)
{
group[i]=new ArrayList<Individual>();
}
You can do thi. Create an Array of type ArrayList
ArrayList<Integer>[] a = new ArrayList[n];
For each element in array make an ArrayList
for(int i = 0; i < n; i++){
a[i] = new ArrayList<Integer>();
}
If you want to avoid Java warnings, and still have an array of ArrayList, you can abstract the ArrayList into a class, like this:
public class Individuals {
private ArrayList<Individual> individuals;
public Individuals() {
this.individuals = new ArrayList<>();
}
public ArrayList<Individual> getIndividuals() {
return individuals;
}
}
Then you can safely have:
Individuals[] group = new Individuals[4];
ArrayList<String> al[] = new ArrayList[n+1];
for(int i = 0;i<n;i++){
al[i] = new ArrayList<String>();
}
you can create a List[] and initialize them by for loop. it compiles without errors:
List<e>[] l;
for(int i = 0; i < l.length; i++){
l[i] = new ArrayList<e>();
}
it works with arrayList[] l as well.

JAVA- how to assign string value to string array dynamically

In my application i got string values dynamically. I want to assign these values to string array then print those values.But it shows an error(Null pointer exception)
EX:
String[] content = null;
for (int s = 0; s < lst.getLength(); s++) {
String st1 = null;
org.w3c.dom.Node nd = lst.item(s);
if (nd.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
NamedNodeMap nnm = nd.getAttributes();
for (int i = 0; i < 1; i++) {
st1 = ((org.w3c.dom.Node) nnm.item(i)).getNodeValue().toString();
}
}
content[s] = st1;
//HERE it shows null pointer Exception.
}
Thanks
This is because your string array is null. String[] content=null;
You declare your array as null and then try to assign values in it and that's why it is showing NPE.
You can try giving initial size to your string array or better to use ArrayList<String>.
ie:
String[] content = new String[10]; //--- You must know the size or array out of bound will be thrown.
Better if you use arrayList like
List<String> content = new ArrayList<String>(); //-- no need worry about size.
For list use add(value) method to add new values in list and use foreach loop to print the content of list.
Use ArrayList or Vector for creating collection (or array) of strings in a dynamic fashion.
List<String> contents = new ArrayList<String>();
Node node = (org.w3c.dom.Node) nnm.item(i)).getNodeValue();
if (null != node)
contents.add(node.toString());
Outside the loop you can do as follows
for(String content : contents) {
System.out.println(content) // since you wanted to print them out
It's a little hard to understand what you're after because your example got munged. However, your String array is null. You need to initialize it, not just declare it. Have you considered using an ArrayList instead? Arrays in java are fixed length (unless they changed this since my university days).
ArrayList is a lot simpler to work with.
E.g.:
List<String> content = new ArrayList<String>();
for (int i = 0; i < limit; i++){
String toAdd;
//do some stuff to get a value into toAdd
content.add(toAdd)
}
There's also something weird with one of your for loops.
for(int i=0;i<1;i++)
The above will only ever iterate once. To clarify:
for(int i=0;i<1;i++){
System.out.println("hello");
}
is functionally identical to:
System.out.println("hello");
They both print out "hello" once, adn that's it.
Use
content[s] = new String(st1);
Now it creates new instance for that particular array index.

For-Each and Pointers in Java [duplicate]

This question already has answers here:
Why does the foreach statement not change the element value?
(6 answers)
Closed 5 years ago.
Ok, so I'm tyring to iterate through an ArrayList and remove a specefic element. However, I am having some trouble using the For-Each like structure. When I run the following code:
ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)
for(String t : arr)
{
t = " some other value "; //hoping this would change the actual array
}
for(String t : arr)
{
System.out.println(t); //however, I still get the same array here
}
My question in, how can I make 't' a pointer to 'arr' so that I am able to change the values in a for-each loop? I know I could loop through the ArrayList using a different structure, but this one looks so clean and readable, it would just be nice to be able to make 't' a pointer.
All comments are appreciated! Even if you say I should just suck it up and use a different construct.
I think the best approach may be to use a for loop.
ArrayList<String> arr = new ArrayList<String>();
for (int i = 0; i < arr.size(); i++) {
String t = arr.get(i);
if (// your condition is met) {
arr.set(i, "your new value");
}
}
The problem is that you're trying to change the loop-scoped reference t to let it point to a new String instance. This ain't going to work. It does not refer the actual entry in the arraylist. You need to change the actual value of the reference. If String was mutable and provided a fictive set() method for that, you could in theory do
for (String t : arr) {
t.set("some other value");
}
or so, but that's not possible as it is immutable. Better get a handle of the entrypoint in the array itself using the normal for loop:
for (int i = 0; i < arr.size(); i++) {
arr.set(i, "some other value");
}
If you insist in using the enhanced for loop, then you need to replace String by StringBuilder, which is mutable:
for (StringBuilder t : arr) {
t.delete(0, t.length()).append("some other value");
}
Remember, Java is pass-by-value, not pass-by-reference.
For-each doesn't give you an index pointer, so you just can't use it to change an immutable value.
Either use a for-loop with an index or use a mutable type (like StringBuffer, not String)
An array of objects (like strings) in Java is a contiguous block containing an ordered series of references. So, when you have an array of 4 strings, what you really have is 4 references stored IN the array, and 4 string objects that are outside of the array but are referenced by its 4 elements.
What the for-each construct in Java does is create a local variable and, for each iteration, copy into that local variable the reference from the array cell that corresponds to that iteration. When you set the loop variable (t = " some other value") you are putting a reference to a new string, "some other value", into the local variable t, not into the array.
The contrasts with some other languages (like Perl) where the loop variable acts like an alias to the array/list element itself.
Your code is re-written by the compiler as something like this:
ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)
for (final Iterator <String> i = arr.iterator(); i.hasNext();) {
String t;
t = i.next();
t = " some other value "; // just changes where t is pointing
}
To do what you want you would have to write the for loop like this:
for (final ListIterator<String> i = arr.iterator(); i.hasNext();) {
final String t;
t = i.next();
i.set("some other value");
}
Iterator does not have the set method, only ListIterator does.
Basically you want to remove the String t from the list arr. Just do a arr.remove(t) and you could be done. But you can't do it while iterating over the same list. You'll get an Exception if you try to modify the list this way.
You have two options:
clone your list, iterate through the clone and remove the 'specific' String from the original list
create a list for delete candidates, add all 'specific' Strings to that list and, after iterating through the original list, iterate through the wastebin and remove everything you've collected here from the original list.
Option 1 is the easist, the clone can be made like:
List<String> clone = new ArrayList<String>(arr);
You seem to misunderstand how objects/references work in Java, which is pretty fundamental to using the language effectively. However, this code here should do what you want (apologies for the lack of explanation):
ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)
for(int i = 0; i < arr.size(); i++)
{
arr.set(i, " some other value "); // change the contents of the array
}
for(String t : arr)
{
System.out.println(t);
}
I believe, this is not related to immutable or mutable.
t = " some other value "; //hoping this would change the actual array
t does not hold the reference to actual object. Java copies the value from arraylist and puts that value into t so array list value does not get affect.
HTH
This has been answered well. Still here is my suggestion. The var t inside loop is only visible there. It will not be seen outside the loop. You could do t.set() if it was not String.
Use a StringBuffer rather than plain strings. This way the string within is mutable.
Strings are immutable. If you had a mutable type like StringBuilder/Buffer, you could change the string in your iteration. You do have references, remember.

Categories

Resources