Any way to insert an anonymous array into a collection? - java

I've found plenty of entries here that say
someFunc(new int[]{1,2,3});
works for calling methods and being used in a for/each loop.
//======
How about for assignment into a collection?
I've tried this:
ArrayList<int[]> data = new ArrayList<int[]>();
data.add(new int[]{21, 19629});
and I get "identifier expected" and "illegal start of type".
Is there any thing I can do to make this work?

You've made a list of arrays. Was that really what you intended, or did you mean to ask about something like
ArrayList<Integer> data = new ArrayList<Integer>();
data.add(new int[]{1,2,3});
?
In any case, familiarize yourself with the Arrays and Collections classes--they contain a lot of utilities that come in handy in cases like this.

Easiest way to make a list from an array:
List<String> myList = Arrays.asList("Hello", "There", "Foo", "Bar);
Note the list is fixed size and backed by the input array so changes to the list actually write to the array. Adding or removing elements will likely result in an UnsupportedOperationException. If you intend to mess around with the array such as adding or removing elements you may need to copy the elements into another list

Check out guava, especially the google collections part.
Several of the collection classes define a static method of(...) which will the add all objects given to that collection.
Combined with static imports this allows very concise colleciton intializations on-the-fly.
e.g.
import static com.google.common.collect.ImmutableList.of;
...
someFunc(of("abc","def","ghi"));
will call someFunc with a list of strings.

In fact, this code works if you want to make a list of table of integers.
public static void main(String[] args) {
List<int[]> data = new ArrayList<int[]>();
data.add(new int[]{21, 19629})
for(int[] tab : data){//I loop each tab (only one here)
for(int i: tab){//I loop each values
System.out.println(i);
}
}
}
print
21
19629

This may be a limitation of the language syntax, or a bug in the spec that the identifier production is being found before the expression production in the parsing of the method call syntax. Don't mix anonymous array declaration inside the method call.
data.add(new int[]{21, 19629});
and I get "identifier expected" and
"illegal start of type".
The "identifier expected" in data.add(...) is probably caused by the compiler expecting an identifier and finding an expression that resolves to an anonymous instance. There are several places where that very syntax is acceptable, I'm not sure why data.add() needs an identifier.
The "illegal start of type" may be that the compiler thinks the expression is an anonymous type declaration but the syntax doesn't allow for that in a method call.
Try creating it using a variable, then pass the variable as the method arg.
int[] nums = new int[] {0,1,2};
data.add(nums);
In looking for more specifics of the ArrayList.add() grammar, I found this answer on a similar problem someone had learning ArrayList. JavaGlossary has a good set of Compile-time errors.

Related

Array List initialization displayed as boolean

I am trying to create an object with the following constructor
public PageBreak(String sheetName, ArrayList<Integer> rowPageBreaks, ArrayList<Integer> columnPageBreaks)
{
this.sheetName = sheetName;
this.rowPageBreaks = rowPageBreaks;
this.columnPageBreaks = columnPageBreaks;
}
In another method, I do the following call:
pageBreaks.add(new PageBreak(teamResultSheet.getName(),
new ArrayList<Integer>().add(teamResultSheet.getRowPageBreak()), null));
I then get the following error message: The constructor PageBreak (String, boolean, null) is undefined.
How can I create an ArrayList<Integer> on the spot?
You're going to want to populate your list before you attempt to use it. Here's what's happening:
You instantiate a new ArrayList<Integer>.
You immediately call add on that list.
The result of add is boolean (and consequently always returns true).
The boolean result is what is interpreted, and not the list.
While Makoto's answer is correct and explains why you are getting this error, and gives you sensible advice to create your ArrayList before you use it, you might want to know if there is any other way you can make your code more succinct.
Unlike more recent languages, such as Groovy or Kotlin, Java unfortunately does not have List literals as a language syntax. There have been some attempts to hack around this limitation; what you may have been attempting with your code is the double brace initialization idiom:
pageBreaks.add(new PageBreak(teamResultSheet.getName(),
new ArrayList<Integer>() {{add(teamResultSheet.getRowPageBreak());}},
null);
Although this may look cute, it does have its drawbacks, as described in the above link.
Do you really need to pass actual ArrayLists to your constructor? Why not make it take Lists, which will make it more flexible:
public PageBreak(String sheetName, List<Integer> rowPageBreaks, List<Integer> columnPageBreaks)
{
...
}
Then you have the freedom to pass it ArrayLists, as before, or any other kind of List:
pageBreaks.add(new PageBreak(teamResultSheet.getName(),
Arrays.asList(teamResultSheet.getRowPageBreak()),
null);
This looks more succinct and doesn't have the former's drawbacks; however, the list is fixed-size and immutable.
If you only want a single-element list, it's more efficient to use the following:
pageBreaks.add(new PageBreak(teamResultSheet.getName(),
Collections.singletonList(teamResultSheet.getRowPageBreak()),
null);

Error on Shuffling xml layouts using ArrayList

I'm new with ArrayList. I don't get it.
If I use int[] as the ArrayList item there is an error saying:
The method put(int) is undefined for the type ArrayList<int[]>.
If I use int the error says:
Syntax error on token "int", Dimensions expected after this token
I tried to use add() still the same...
You can't use primitive types int etc, as the "type" of an ArrayList. You must use the wrapper class Integer instead. Also, I stand to be corrected, but I don't think you can have an ArrayList of an array type for similar reasons. Perhaps ArrayList<ArrayList<Integer>> would work, as slightly ugly as that is?
EDIT: And while my Android experience is somewhat minimal and rusty, ρяσѕρєя K's comment about R.layout.foo always returning an int is certainly right.
Use something like this :
ArrayList<Integer []> mArrayList = new ArrayList<Integer[]>();
Integer [] layouts = {R.layout.layout1,R.layout.layout12,...};
mArrayList.add(layouts);
ArrayList<Integer> mArrayList = new ArrayList<Integer>();
mArrayList.add(R.layout.layout1);
mArrayList.add(R.layout.layout2);
...

List of list iteration in code below -- which is better approach?

I am iterating over a List of Lists. In my code listofuserdetailsperAccount is List<List>. I am considering the two methods below, please let me know which way is correct, more efficient and should be followed in java coding.
Way 1-----
for(int i=0;i<=listofuserdetailsperAccount.size();i++){
List list=(List) listofuserdetailsperAccount.get(0);
}
Way 2---
for(int i=0;i<=listofuserdetailsperAccount.size();i++){
List list= new ArrayList();
list=(List) listofuserdetailsperAccount.get(0);
}
I'll go with for each loop
for( List userDetailsPerAccount : listOfUserDetailsPerAccount ) {
//anything you want to do with userDetailsPerAccount
}
Way 1 is better approach than Way 2. In Way 2 List list= new ArrayList(); it will create a extra ArrayList object which does not have any use, which will cause memory consumption for sometime.
And it is also recommended use type specific List<E> so that you dont cast at runtime it will be typesafe.
for(List<E> list : listOfUserDetailsPerAccount){
...
}
In Java 5 and above use for-each.
You have a couple of problems here, with both proposed solutions.
Your List<List> listofuserdetailsperAccount object is not properly typed, as the inner List is a raw type, something to be avoided. Assuming your inner list holds UserDetail objects, your list of lists should be of type List<List<UserDetail>>.
You don't use the for-each loop syntax to iterate over a List, which is Iterable.
for(List<UserDetail> innerList : listofuserdetailsperAccount)
In Way 2 you initialize List to a new ArrayList (which is a raw type, it should be new ArrayList<>() if you needed this) and then promptly overwrite this value with the contents of your outer list. This means you ask Java to construct a new object that is then immediately cleaned up by the garbage collector, unused. This is wasteful and unnecessary.
In summary, you likely want to do:
List<List<UserDetail>> listofuserdetailsperAccount = // initialize your list
for(List<userDetail> innerList : listofuserdetailsperAccount) {
// do work with your innerList now
}
You commented (tidied up):
So while initializing I am doing something like this now, can you please let me know if this is correct:
List<List<String>> listofAccountdetailsLoggedinUser = null;
listofAccountdetailsLoggedinUser = new ArrayList<List<String>>();
OR I should not put it as null and directly create an object like this:
List<List<String>> listofAccountdetailsLoggedinUser =
new ArrayList<List<String>>();
That is the right track, but you do not need to initialize the variable to null. It doesn't hurt anything, since it doesn't construct an unnecessary object, but there's no reason to - you can declare and initialize the variable in one line, like you do in your second example.
Additionally, you don't need to specify the type of the ArrayList on the right hand side, simply use the diamond operator <>, like so:
List<List<String>> listofAccountdetailsLoggedinUser = new ArrayList<>();
Also, consider a shorter variable name, there's no need to use such a long one, and it's no fun to type :)

Vararg initialization with parameters from array (Java)

Antescript: I'm aware that there's a prior SO question whose title sounds like it refers to the exact same question. It doesn't.
Anyway, this question is a little weird - there are plenty of better ways to work around the issues here, but I'm curious as to how I could solve my particular dilemma.
Let's say I have a method that uses varargs to accept an arbitrary number of elements, perhaps of type Integer. If I have an arbitrary-length array of Integers, is there a way for me to call my method with a comma-separated param list composed of each element of said array?
Here's a brief, contrived example:
Integer[] paramList = new Integer {1, 2, 3};
varMethod(paramList[0], paramList[1], paramList[2]);
// varMethod({{for (param : paramList) {param;}}});
public void varMethod(Integer...values) {
for (Integer value : values) {
foo(value);
}
}
That commented-out line hints at what I want to do. Since the paramList integer is arbitrary length, calling varMethod with each element explicitly requested (line 2) won't work. What I'm wondering is if there's a way to dynamically generate the comma-separated param list from the elements of an array.
Again, I realize that in an example like this, there are better ways to approach the entire problem, but please be aware that I've simplified the code so that it's only relevant to the particular issue we're discussing here. Any workarounds that address my posted code won't generalize to the problem I'm really working on that led me to formulate this question in the first place.
I think you're just looking for:
varMethod(paramList);
Perhaps you didn't realize that Integer... is a special variant of a normal Integer[] array. Thus since paramList is already an Integer[] array, you can just pass it directly into the method.
You can just call
varMethod(paramList);

How does one instantiate an array of maps in Java?

I can declare an array of maps using generics to specify the map type:
private Map<String, Integer>[] myMaps;
However, I can't figure out how to instantiate it properly:
myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning
How can I instantiate this array of maps without getting a compiler error or warning?
Update:
Thank you all for your replies. I ended up going with the List suggestion.
Not strictly an answer to your question, but have you considered using a List instead?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
seems to work just fine.
See Java theory and practice: Generics gotchas for a detailed explanation of why mixing arrays with generics is discouraged.
Update:
As mentioned by Drew in the comments, it might be even better to use the Collection interface instead of List. This might come in handy if you ever need to change to a Set, or one of the other subinterfaces of Collection. Example code:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
From this starting point, you'd only need to change HashSet to ArrayList, PriorityQueue, or any other class that implements Collection.
You can't safely create a generic array. Effective Java 2nd Edition goes into the details in the chapter on Generics. Start at the last paragraph of page 119:
Why is it illegal to create a generic
array? Because it isn’t typesafe. If
it were legal, casts generated by the
compiler in an otherwise correct
program could fail at runtime with a
ClassCastException. This would violate
the fundamental guarantee provided by
the generic type system.
To make this more concrete, consider
the following code fragment:
// Why generic array creation is illegal - won't compile!
List<String>[] stringLists = new List<String>[1]; // (1)
List<Integer> intList = Arrays.asList(42); // (2)
Object[] objects = stringLists; // (3)
objects[0] = intList; // (4)
String s = stringLists[0].get(0); // (5)
Let’s pretend that line 1, which
creates a generic array, is legal.
Line 2 creates and initializes a
List<Integer> containing a single
element. Line 3 stores the
List<String> array into an Object
array variable, which is legal because
arrays are covariant. Line 4 stores
the List<Integer> into the sole
element of the Object array, which
succeeds because generics are
implemented by erasure: the runtime
type of a List<Integer> instance is
simply List, and the runtime type of a
List<String>[] instance is List[], so
this assignment doesn’t generate an
ArrayStoreException. Now we’re in
trouble. We’ve stored a List<Integer>
instance into an array that is
declared to hold only List<String>
instances. In line 5, we retrieve the
sole element from the sole list in
this array. The compiler automatically
casts the retrieved element to String,
but it’s an Integer, so we get a
ClassCastException at runtime. In
order to prevent this from happening,
line 1 (which creates a generic array)
generates a compile-time error.
Because arrays and generics don't combine well (as well as other reasons), it's generally better to use Collection objects (in particular List objects) rather than arrays.
In general it is not a good idea to mix generics and arrays in Java, better use an ArrayList.
If you must use an array, the best way to handle this is to put the array creation (your example 2 or 3) in a separate method and annotate it with #SuppressWarnings("unchecked").
You can create generic array of map
Create list of map.
List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
Initialize array.
Map<String,?>[]myDataArray=new HashMap[myData .size()];
Populate data in array from list.
myDataArray=myData.toArray(myDataArry);
Short answer appears to be that you really just can't.
See the following for a blog about it.
http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/
One of the comments to the blog states that:
Actually, the engineers made the creation of such an Array illegal. So the creation of an array from generic Class fails. The Collection.toArray method followed by a Cast to the Array works at compile time.
This solves not the problem, that the ArrayStoreCheck can’t be done during Runtime, but you can create an Array of generics in this way.
As suggested by Bill the Lizard, you probably are better off using a
List<Map<String,Integer>>
I know its a bit late to reply but I found this workaround helpful for my case...Hope it helps!
Use an array of HashMap to store HashMaps..
public static void main(String[] args) {
HashMap[] arr = new HashMap[1];//creating an array of size one..just for sake of example
HashMap<String, String> arrMap = new HashMap<String, String>();
//use loops to store desired key-value pairs into the HashMap which will be stored inside the array
arrMap.put("ABC", "Name");
//use loop to store your desired hashMap into the array at a particular index
arr[0] = arrMap;
//desired manipulation of the stored array.
System.out.println(arr[0]);
}
myMaps = new HashMap<String, Integer>[10]();
So that's Wrong
Why not make a List of Maps instead of trying to make an array?
List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);

Categories