I'm trying to initialize a List in Java but I want to know if there's a more elegant way of initializing multiple lists with the same types.
So far I've done the following:
List<Model> list1 = new List<>();
List<Model> list2 = new List<>();
List<Model> list3 = new List<>();
But I'm trying to initialize about 10 different lists of the same type and it seems very ugly.
I've also tried doing:
List<Model> list1, list2, list3 = new List<>();
But this doesn't work.
After searching for the answer, all I could find were tips on how to initialize an array with multiple variables in one line using the asList() method but that's not what I'm trying to do.
Is this even possible?
You can use a Map where the key represents the list name and the value represents a List
Map<String,List<Model>> lists = new HashMap<>();
You can then populate the list in a for loop :
for(int i=0;i<10;++i) {
lists.put("list"+(i+1),new ArrayList<Model>());
}
You can access the lists using :
lists.get("list1").add(new Model(...));
lists.get("list2").add(new Model(...));
Disclaimer : I have not tried compiling this code since I am not on a computer.
If you have 10 lists or whatever, it's time to think: probably you need an array or list of lists.
List<List<Model>> lists = new ArrayList<>();
for(int i=0; i<10; i++) lists.add(new ArrayList<>());
// later in code instead of list5.add(...)
lists.get(5).add(...)
List is an interface (abstract type) and cannot be instantiated. You will have to use ArrayList as shown below. You can try:
List<Model> list1 = new ArrayList<Model>(), list2 = new ArrayList<Model>();
This should work as well
List<Model> list1 = new ArrayList<Model>(), list2 = new ArrayList<Model>(), list3 = new ArrayList<Model>();
The closest possible thing that you can do is following
List<Model> a = new ArrayList<>(), b = new ArrayList<>(), c = new ArrayList<>(), d = new ArrayList<>();
But either of the approach you consider has same memory consumption impact.
Here's my answer:
#SuppressWarnings({"unchecked"})
List<Model>[] lists = new List[3];
for(List list : lists) {
list = new ArrayList<Model>();
}
List<Model> list1 = lists[0];
List<Model> list2 = lists[1];
List<Model> list3 = lists[2];
Related
ArrayList<ArrayList<Integer>> treeList = new ArrayList<>();
ArrayList<Integer> aList = new ArrayList<>();
ArrayList<Integer> bList = new ArrayList<>();
aList.add(1);
treeList.add(aList);
bList = treeList.remove(0);
aList.clear(); //bList will be cleared
I know that bList and aList will refer to the same object,so when aList.clear(), bList will clear too, is there any way to make bList a new object.
... is there any way to make bList a new object.
You can copy it; e.g.
bList = new ArrayList<>(treeList.remove(0));
See How to copy Java Collections list
Actually, this looks like a case that would benefit from writing your own custom classes.
As written, your treeList is an open data structure. Anything that has access to treeList or any of its component ArrayList objects can interfere with it. That's OK in some circumstances. But if you want to protect against having different parts of your codebase "mess up" the data structure then you should put the data structure behind an abstraction boundary; e.g.
public class MyThing {
private ArrayList<ArrayList<Integer>> treeList = new ArrayList<>();
public void add(ArrayList<Integer> l){
treeList.add(new ArrayList<>(l));
}
public void remove(int index) {
return new ArrayList<>(treeList.remove(index));
}
}
Notice that MyThing carefully copies the lists when it adds them and when it removes them so that one client of the MyThing API cannot interfere with another one via shared lists.
Obviously, there is a cost in doing this.
Try this. Pass the return of the remove as an argument to the ArrayList constructor.
ArrayList<ArrayList<Integer>> treeList = new ArrayList<>();
ArrayList<Integer> aList = new ArrayList<>();
ArrayList<Integer> bList = new ArrayList<>();
aList.add(1);
treeList.add(aList);
bList = new ArrayList<>(treeList.remove(0));
aList.clear(); //bList will be cleared
System.out.println(bList);
Prints
[1]
Alternatively, instead of assigning:
bList = treeList.remove(0);
you can use List#addAll
bList.addAll(treeList.remove(0));
Am trying to filter elements from list of arraylist using Google's Guava filter and its only supports for Collection E. I have to filter elements from List of ArrayLists.
Please find my below code that am working for it.
Is there any solution to filter elements from List of Arraylists ?
ArrayList<ArrayList<String>> lists=new ArrayList<ArrayList<String>>();
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
ArrayList<String> list3 = new ArrayList<String>();
list1.add("Hello");
list1.add("hi");
list1.add("howdy");
list2.add("are you good");
list2.add("you doing");
list2.add("was the day");
list3.add("who");
list3.add("how");
list3.add("where");
lists.add(list2);
lists.add(list1);
lists.add(list3);
Collection<String> filtered=Collections2.filter(lists, Predicates.containsPattern("dy")); // not able to filter from List of ArrayLists.
System.out.println("Filtered -->"+filtered);
Update 1
Please find my implementation below :
Collection<Menu> menus = menuRepository.getMenus();
Collection<ArrayList<Menu>> enabledMenus = FluentIterable.from(menus)
.transformAndConcat(Functions.identity())
.filter(byDisabled())
.toList();
Am getting the below error
The method transformAndConcat(Function<? super Menu,? extends Iterable<? extends T>>) in the type FluentIterable<Menu> is not applicable for the arguments (Function<Object,Object>)
Please find my byDisabled() method implementation below.
private Predicate<ArrayList<ArrayList<Menu>>> byDisabled() {
return new Predicate<ArrayList<ArrayList<Menu>>>() {
#Override
public boolean apply(ArrayList<ArrayList<Menu>> menu) {
return isMenuEnabled(menu);
}
};
}
(Assuming you don't use Java 8, otherwise other answers already show possible solutions.)
You need a .flatMap equivalent in Guava, which are:
Iterables#concat(Iterable)
FluentIterable#transformAndConcat(Function)
The latter can be used fluently (duh), similarly to Java 8 approach:
ImmutableList<String> filtered = FluentIterable.from(lists)
.transformAndConcat(Functions.identity())
.filter(Predicates.containsPattern("dy"))
.toList();
Note that this copies contents of a resulting iterable, so if lazy Iterable is enough, last step could be omitted:
Iterable<String> filtered = FluentIterable.from(lists)
.transformAndConcat(Functions.identity())
.filter(Predicates.containsPattern("dy"));
Read more about Iterables and FluentIterable on Gauva wiki.
You can use Java 8's native stream API for this
List<String> filtered = lists.stream()
.flatMap(Collection::stream)
.filter(Predicates.containsPattern("dy"))
.collect(Collectors.toList());
Not sure whether guava is the only option for you, if not, Java 8 stream may work:
If you only want to find out the matched elements, try:
ArrayList<ArrayList<String>> lists = new ArrayList<>();
ArrayList<String> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<String> list3 = new ArrayList<>();
list1.add("Hello");
list1.add("hi");
list1.add("howdy");
list2.add("are you good");
list2.add("you doing");
list2.add("was the day");
list3.add("who");
list3.add("how");
list3.add("where");
lists.add(list2);
lists.add(list1);
lists.add(list3);
List<String> matchedItems =
lists.stream().flatMap(Collection::stream).filter(str -> str.contains("dy")).collect(Collectors.toList());
for (String item : matchedItems) {
System.out.println("Matched item: " + item);
}
Note, relation between element and sub-list is lost in this solution.
This code doesn't work;
ArrayList<BlockFace> cardinalDirections = new ArrayList<>();
cardinalDirections.addAll(new BlockFace[] {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST});
And neither does this;
ArrayList<BlockFace> cardinalDirections = Arrays.asList(new BlockFace[] {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST});
It only works if I add each element manually one at a time, or iterate through the array;
ArrayList<BlockFace> cardinalDirections = new ArrayList<>();
for (BlockFace face : new BlockFace[] {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST})
cardinalDirections.add(face);
Why don't the top two examples work?
Your approach does not work because ArrayList.addAll takes Collection not an array.
Converting enum to ArrayList
List<BlockFace> list = Arrays.asList(BlockFace.values());
Is there a way to put contents of mulitple Lists to a Set? (Eliminating the duplicates)
For example contents of listA, listB, listC all be put in a Set. (Assuming they are of same type)
You certainly can.
The Set will add all of the elements from each of the lists and then remove any duplicate objects based on the objects equals and hashCode() methods. (When implementing one, you should implement the other.)
List<Object> listA = new ArrayList<Object>();
List<Object> listB = new ArrayList<Object>();
List<Object> listC = new ArrayList<Object>();
Set<Object> set = new HashSet<Object>();
set.addAll(listA);
set.addAll(listB);
set.addAll(listC);
EDIT: Did Some Testing
Here's a little test method that shows this in action:
public static void main(final String[] args) {
final String one = new String("one");
final String two = new String("two");
final String three = new String("three");
final String four = new String("four");
final List<String> listA = new ArrayList<String>();
listA.add(one);
listA.add(two);
final List<String> listB = new ArrayList<String>();
listB.add(two);
listB.add(three);
final List<String> listC = new ArrayList<String>();
listC.add(three);
listC.add(four);
final Set<String> set = new HashSet<String>();
set.addAll(listA);
set.addAll(listB);
set.addAll(listC);
System.out.println(set);
}
And the output is:
[two, one, three, four]
This shows the implementation working, but you should obviously keep in mind that the order of the remaining objects might not be want you anticipate or desire.
Yes, you may declare a set of lists, if that's what you're looking for.
Set<List<SomeType>> mySet = new Set<>();
mySet.add(listA);
mySet.add(listB);
mySet.add(listC);
I am using Eclipse Juno and Java.
I want to create a list and then store that list in another list so I can pass the list of lists to the server side. I have tried:
ArrayList<T> listAccountAndCubs = new ArrayList<Comparable>();
listAccountAndCubs.add(accountId);
listAccountAndCubs.add(sqlDateArchived);
However, I can not get the values "T" and "Comparable" correct. I tried "String" however that does not work for storing the date.
Once the above is correct how do I set up the list to contain "listAccountAndCubs"?
Thanks for any assistance,
Glyn
this is how you can create a list
List<String> l = new ArrayList<String>();
this is how you can create list of list
List<List<Comparable>> listOfList = new ArrayList<List<Comparable>>();
listOfList.add(new ArrayList<Comparable>());
...
Sounds like you want something like this
List<List<String>> listAccountAndCubs = new ArrayList<List<String>>();
I would recomment using Google Guava library to clean the syntax a bit
List<List<String>> listAccountAndCubs = Lists.newArrayList();
List<ArrayList<Comparable>> listAccountAndCubs = new ArrayList<>();
or
List<String> l1=new ArrayList<>();
List<List<String>> l2=new ArrayList<>();
l1.add("a");
l2.add(l1);
If I understand you crrectly you want to have a list of Strings, and store this in another list?
List<String> sl = new ArrayList<String>();
List<List<String>>sls = new ArrayList<List<String>>();
sls.add(sl);
sl.add("String 1");
The value "T" is just a placeholder for the type, as the list is a generic interface, which can take any arbitrary object.
If you want to create a list of unspecified types, you would use
List<?>list = new ArrayList<?>();
Then you can add untyped objects to it, but in your case this is not neccessary.
Instead you can of course also create a list of comparables. Like this:
List<Comparable<String>>list = new ArrayList<Comparable<String>>();