I would like to know how to create a linked list of linked lists. Also, It would be helpful if the predefined LinkedList (class from Java) and its methods are used for defining and for other add, get, listIterating operations.
You can put any object in a list, including another list.
LinkedList<LinkedList<YourClass>> list = new LinkedList<LinkedList<YourClass>>();
is a LinkedList of LinkedLists of YourClass objects. It can also be written in a simplified way since Java 7:
LinkedList<LinkedList<YourClass>> list = new LinkedList<>();
Very simple examples of manipulating such a list:
You then need to create each sublist, here adding a single sublist:
list.add(new LinkedList<YourClass>());
Then create the content objects:
list.get(sublistIndex).add(new YourClass());
You can then iterate over it like this (sublists' items are grouped by sublist):
for(LinkedList<YourClass> sublist : list) {
for(YourClass o : sublist) {
// your code here
}
}
If you want to add specific methods to this list of lists, you can create a subclass of LinkedList (or List, or any other List subclasses) or you can create a class with the list of lists as a field and add methods there to manipulate the list.
Well i've done this code and i've got it right
java.util.LinkedList mainlist = new java.util.LinkedList();
java.util.LinkedList sublist1 = new java.util.LinkedList();
sublist1.add(object1);
sublist1.add(object2);
sublist1.add(object3);
java.util.LinkedList sublist2=new java.util.LinkedList();
sublist2.add(1);
sublist2.add(2);
mainlist.add(sublist1);
mainlist.add(sublist2);
// To retrieve the sublist1 from mainlist...........
java.util.LinkedList temp = (java.util.LinkedList)mainlist.get(0);
Here variable mainlist is LinkedList of LinkedLists and variable temp contains the value the first list stored i.e sublist1..
You can even simplify access to the secondary lists, e.g. using
final List<List<String>> lists = new LinkedList<List<String>>() {
#Override
public List<String> get(final int index) {
while (index >= size()) {
add(new LinkedList<>());
}
return super.get(index);
}
};
This code automatically adds new LinkedLists to the outer list. With this code you can later easily add single values:
lists.get(2).add("Foo");
LinkedList<LinkedList<YourClass>> yourList = new LinkedList<LinkedList<YourClass>>();
As the declaration. To add another linked list (to the end by default) you would do
yourList.add(new LinkedList<YourClass>());
To add an element to lets say the second linked list in the series:
yourList.get(1).add(new YourClass());
Related
I just came across this code that works
List<List<Integer>> parentList = new ArrayList<>();
LinkedList<Integer> curList = new LinkedList<>();
parentList.add(curList);
I guess I was a bit thrown off because I didn't expect you'd be able to add a LinkedList to something declared as a List. I thought you would have had to do something like
List<Integer>curList = new LinkedList<>();
parentList.add(curList);
I thought the whole point of declaring / initializing a LinkedList or ArrayList as a List was so that you could add them to a List even though they are implemented as LinkedLists and ArrayLists.
edit: Or am I getting confused with the fact that we do this as an abstraction layer - we declare it as a List so that even if its made up of arraylists and linkedlists, we can still use the same List interface functions on all of them. And we can add linkedlists to a List of Lists because linkedlists are just implementing the List interface
LinkedList extends AbstractSequentialList which in turns extends AbstractList and ArrayList extends AbstractList.
So both LinkedList and ArrayList underlying extend the same subclass. The add method on a List interface has a restriction to add elements of similar type. Therefore both LinkedList and ArrayList are considered to be similar and therefore are allowed to be added.
Also logically adding the LinkedList doesn't changes the behavior of elements inside it as the order is maintained even after getting added to the list.
tl;dr
This:
LinkedList < Integer > curList = new LinkedList<>() ; // <-- Declared as `LinkedList`.
parentList.add( curList ) ;
… and this:
List < Integer > curList = new LinkedList<>() ; // <-- Declared as `List`.
parentList.add( curList ) ;
… have the same effect.
In both cases, parentList is expecting to receive a List that holds Integer objects. A LinkedList is simultaneously both a LinkedList and a List. So passing curList defined as a List or defined as a LinkedList makes no difference. In both cases a List is received by the parentList.add method.
Assigning a LinkedList object to a List variable does not change the nature of the object.
List means any kind of List implementation: ArrayList, LinkedList, whatever
Your first collection, parentList, is a list of lists.
Each element within that list is itself another list. The declaration List< List < Integer > > parentList tells us that we have a list of lists of Integer objects.
Both the outer list and the inner lists can be any kind of List, not necessarily an ArrayList or LinkedList.
Your second collection, curList, is simply a list of Integer objects.
We know this from its declaration, LinkedList < Integer > curList.
In this declaration, we are saying the list is definitely a LinkedList, not any other kind of List.
Here is a full example.
First we make a List object holding lists of Integer objects. This outer list is empty.
Then we add a list of three single-digit odd numbers (3, 5, 9). This non-modifiable list is generated by the List.of method. The concrete implementation of List used for the object returned by List in not promised, and may vary with the situation and the version of Java. All we know for sure is that we are getting some implementation of List that holds Integer objects.
Then we create a LinkedList holding Integer objects. After adding a couple of double-digit numbers, we add the list to the outer list.
Here are the key points to this code that seem to be confusing you:
We could have declared this curList variable as the more general List < Integer > curList rather than the more specific LinkedList < Integer > curList. The type of List used for curList is irrelevant. The outer list parentList has said it does not care about which List implementation is added as an element, only that the added element be some kind of List that holds Integer objects.
We could decide that the outer list would be better served if it were a LinkedList rather than an ArrayList. If we so decide, we could simply change List< List < Integer > > parentList = new ArrayList<>(); to List< List < Integer > > parentList = new LinkedList<>(); — and none of the other code would break. We can switch new ArrayList to new LinkedList without changing any other code. That is the benefit of polymorphism in OOP.
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
List< List < Integer > > parentList = new ArrayList<>();
parentList.add( List.of( 3 , 5 , 9 ) ) ; // `List.of` returns *some* kind of (unmodifiable ) `List`; we do not know the concrete class nor do we care.
LinkedList < Integer > curList = new LinkedList<>();
curList.add( 21 ) ;
curList.add( 42 ) ;
parentList.add(curList);
System.out.println( parentList ) ;
}
}
See this code run live on IdeOne.com.
[[3, 5, 9], [21, 42]]
In that output, we see a collection, a List that contains two elements. Each element is itself a List, a list of Integer element. The first element of the outer list holds a reference to a list of three Integer objects as elements, while the second element of the outer list holds a reference to a list of two Integer objects as elements.
You said:
I guess I was a bit thrown off because I didn't expect you'd be able to add a LinkedList to something declared as a List.
That something (parentList) is declared as a list of lists. The LinkedList you are passing is a List, so it fits, it is a matching type. Any LinkedList is also a List.
If you wanted the outer list (parentList) to hold only ArrayList objects rather than any kind of List, you would have declared it as:
List< ArrayList < Integer > > parentList = new ArrayList<>();
With such a declaration, passing new LinkedList<>() to its add method would have resulted in a compiler error. Square peg, round hole.
But you would only make a declaration if your code later has a need for methods that are exclusive to ArrayList class, that are not defined in the more general List interface. Generally, you should use the most general interface or superclass that meets your needs, rather than the more specific concrete class or sub-interface. If List has the methods your later code needs, then declare List< List < Integer > > parentList. This gives you flexibility.
You said:
I thought you would have had to do something like
List<Integer>curList = new LinkedList<>();
parentList.add(curList);
When you assign a LinkedList object to a List variable, you are not changing anything. A LinkedList object is simultaneously both a ListedList and a List.
When you pass curList to the parentList.add method, all that method sees is a List. Whether you declare curList as a List or LinkedList does not matter to the add method. The compiler checks that whatever is being passed into add is (a) some kind of List implementation, any List implementation, and (b) holds Integer objects.
I have two filled lists.
The first list contains for example:
"Shoppinglist-fruit", "Shoppinglist-drinks", "Shoppinglist-dinner"
The second list contains:
"Shoppinglist-drinks"
Now i wanna print all items in the first list, except if there's a same object in the second list with the same name (Shoppinglist-drinks).
Looking like:
"Shoppinglist-fruit", "Shoppinglist-dinner"
So how can i check if the name of the object inside the second list is also in one of the objects of the first list.
Eventually i want to end up with a string containing all the names of the shoppinglists that are in the first list and not in the second one.
I started with some code below but i haven't been able to finish it.
I have the two lists, one called listShoppinglists, this is a list filled with different shopping lists.
And the second list filled with somebody's shoppinglists.
So i wanna check if the name of the shoppinglists are equal.
If done that by doing so.
public String getAllShoppingLists(List listShoppinglists, Customer customer, List shoppinglists) {
String namesOfTheShoppingListNames = ""
for (Shoppinglist shoppinglist : listShoppinglists) {
for (int i = 0; i < customer.shoppinglists.size(); i++) {
if (customer.shoppinglists.get(i).getName().equals(shoppinglist.getName())) {
// Some action here
}
}
}
return namesOfTheShoppingListNames;
}
You can try this:
List<ShoopingList> firstShoppingListNames = new ArrayList<>();
firstShoppingListNames.add(new ShoppingList("fruit"));
firstShoppingListNames.add(new ShoppingList("dinner"));
firstShoppingListNames.add(new ShoppingList("juice"));
List<ShoppingList> secondShoppingListNames = new ArrayList<>();
secondShoppingListNames.add(new ShoppingList("fruit"));
List<ShoppingList> distinct = firstShoppingListNames.stream().
filter( list -> secondShoppingListNames.stream().
noneMatch(o -> o.getName().equals(list.getName()))).
collect(Collectors.toList());
distinct.forEach(o -> System.out.print(o.getName()));
In this case you are using stream to achieve what you want. You filter first list to obtain those elements, which are not present in other list.
Additionaly if you want to obtain only names of those lists you can use map:
List<String> distinct = firstShoppingListNames.stream().
filter( list -> secondShoppingListNames.stream().
noneMatch(o -> o.getName().equals(list.getName()))).
map(ShoppingList::getName).collect(Collectors.toList());
Use Collections.removeAll() method to do this. Quoted from JavaDoc:-
Removes all of this collection's elements that are also contained in
the specified collection (optional operation). After this call
returns, this collection will contain no elements in common with the
specified collection
.List<String> list1=new ArrayList<String>();
list1.add("Shoppinglist-fruit");list1.add("Shoppinglist-drinks");list1.add("Shoppinglist-dinner");
List<String> list2=new ArrayList<String>();
list2.add("Shoppinglist-drinks");
list1.removeAll(list2);
System.out.println(list1);
//Output:- [Shoppinglist-fruit, Shoppinglist-dinner]
In case, lists contains a custom objects, override equals and hashcode methods in that custom object.
I have a ArrayList as below.
ArrayList<ArrayList<String>> a = new ArrayList<ArrayList<String>>();
Where ArrayList 'a' contains two ArrayList of string as below.
[a,b,c,d] & [1,2,3,4]
How to merge these two list into a single list as below.
[a,b,c,d,1,2,3,4]
Thanks In Advance.
You combine a foreach loop and the addAll method.
Example
ArrayList<String> combined = new ArrayList<String>();
for(ArrayList<String> list : a) {
combined.addAll(list);
}
How this works?
A for each loop will traverse through every member of a Collection. It has a temporary variable, in this case list that it assigns the current element too. All you're doing is adding every element inside each value for list, to one ArrayList named combined.
Just iterate through all the inner lists of a using foreach loop and addAll to result arraylist
ArrayList<String> merged = new ArrayList<String>();
for(ArrayList<String> list : a){
merged.addAll(list);
}
EDIT:
As #Lubo pointed out.
Note that this way you can end up with many arrays being created and thrown away internally in ArrayList. If you have large lists (number of contained elements), consider looking here: Union List
This should work
ArrayList<ArrayList<String>> a = new ArrayList<ArrayList<String>>();
List<String> result = new ArrayList<String>();
for (ArrayList<String> arrayList : a) {
result.addAll(arrayList);
}
Look into main loop and get each list in it and add to your result list.
We have some other ways too, If you can use Apache commons-collection
ListUtils.union(java.util.List list1, java.util.List list2)
Returns a new list containing the second list appended to the first list.
Use ArrayList.addAll(). Something like this should work (assuming lists contain String objects; you should change accordingly).
List<String> combined = new ArrayList<String>();
combined.addAll(firstArrayList);
If you need an Iterable, you can use Guava:
Iterables.concat(Iterable<? extends Iterable<? extends T>> inputs)
And if you really need a List, you can cast a resulting Iterable to a List using this:
Lists.newArrayList(Iterable<? extends E> elements)
or
Lists.newLinkedList(Iterable<? extends E> elements)
Java 8 streams provide another solution:
List<List<String>> list = Arrays.asList(
Arrays.asList("1", "2"),
Arrays.asList("3", "4"),
Arrays.asList("5", "6")
);
List<String> merged = list
.stream()
.reduce(new ArrayList<>(),(accumulator, sublist) -> {accumulator.addAll(sublist);return accumulator;});
System.out.println(merged);
It is similar to the accepted answer: you loop through your list (using Stream.reduce) to add all of your sublists elements to your merged list.
List<Integer> one = Arrays.asList(1, 2,3);
List<Integer> two = Arrays.asList(4, 5,6);
List<Integer> out = Stream.of(one, two)
.collect(ArrayList::new, (listStream, item) -> listStream.addAll(item), (item1, item2) -> {});
System.out.println(out);
Merging lists without loop with Guava
Using FluentIterable.transformAndConcat.
Applies function to each element of this fluent iterable and returns a fluent iterable with the concatenated combination of results. function returns an Iterable of results.
Usage
List<String> combined = FluentIterable.from(a)
.transformAndConcat(Functions.identity())
.toList();
I'm looping through a List to find a particular entry, then assigning that to a variable and trying to remove it later. It's easier to demo than to explain.
ArrayList<Example> list1 = populate();
Example ex1 = list1.get(0);
Example ex2 = ex1;
list1.remove(ex2);
I know this likely has something to do with Java's inability to handle pointers, but a viable solution would be great.
Edit: To elaborate, this is a brief example of my code rather than giving you the full thing. What I'm doing is iterating through a list to find the lowest 10 numbers. My technique is to go through the list, find the lowest and add it to another list, then remove that number from the original list and repeat. But my list is made of objects which have an int value inside them, rather than a list of integers.
for(0 to 9){
for(0 to list.size){
if(list.get(x) < smallest)
smallest = list.get(x)
}
smallestList.add(smallest);
list.remove(smallest)
}
I would sort the list. Then, I would create a list with those 10 smallest objects and change the original list list1 to contain the remaining objects. Something like:
Collection.sort(list1);
ArrayList<Example> yourSmallestElements = (ArrayList<Example>)(list1.sublist(0, 9).clone());
list1.removeAll(yourSmallestElements);
NOTE: I cloned the sublist because sublist() only returns a view of the list list1, and that's not what you want here.
Your class Example can implement "Comparable" so that you can define how they need to be compared. You will need to implement the method compareTo(). Something like this:
public class Example implements Comparable<Example> {
private int integerVal = <a value>;
public int compareTo(Example exampleObject) {
return exampleObject.integerVal - this.integerVal;
}
}
Have a look at this link, more precisely the class that begins as follows:
public class Fruit implements Comparable<Fruit>{
If you want to sort your objects...
Example e;
int min=-1; // assuming the list has +ve numbers only
for (Example elem : yourList)
{
if ( elem.gtVaribale() <= min ) //assuming you have variable field in your object
{
e = elem;
min = elem.getVariable();
}
}
yourList.remove(e);
//repeat this for remaining elements of the list
//you can create another sorted list, and do sortedList.add(e), so that sortedList
//have objects in ascending order (of the variable you want to sort) of objects you had in yourList
This is just a pseudoCode and I have not compiled it.
Here you will have to override the comparable method for class Example.
You have to let compiler know which way it should compare your e variable to its list's elements so as to remove it.
I have 9 different ArrayList and I want to have a list of the top 5.
I'm thinking of sorting those ArrayLists by their sizes.
Is it possible to do that? If so, how can I achieve that?
After a few try i finally got it working, just want to share it with everyone.
it will be better to get the size of the arraylist and add it to the big arraylist
// creates an ArrayList that holds ArrayLists
List allTheLists = new ArrayList();
allTheLists.add(pbaustraliaList.size());
allTheLists.add(pbotherList.size());
allTheLists.add(pbunitedStatesList.size());
allTheLists.add(pbunitedKingdomList.size());
allTheLists.add(pbchinaList.size());
allTheLists.add(pbgermanyList.size());
allTheLists.add(pbindiaList.size());
allTheLists.add(pbjapanList.size());
allTheLists.add(pbsingaporeList.size());
Comparator comparator = Collections.reverseOrder();
Collections.sort(allTheLists,comparator);
//display elements of ArrayList
System.out.println("ArrayList elements after sorting in descending order : ");
for(int i=0; i<allTheLists.size(); i++) {
System.out.println(allTheLists.get(i));
}
What you could do is the following:
// this List of lists will need to contain
// all of the ArrayLists you would like to sort
List<ArrayList> allTheLists;
Collections.sort(allTheLists, new Comparator<ArrayList>(){
public int compare(ArrayList a1, ArrayList a2) {
return a2.size() - a1.size(); // assumes you want biggest to smallest
}
});
This will sort the list of lists by the length of each list. The first element in the sorted list will be the longest list, and the last one will be the shortest list.
Then, you can iterate through the first 5 lists to see what the top 5 were.
Some links for reference:
Sorting tutorial
Collections Javadoc
Comparator Javadoc
Depending on how you have your ArrayLists stored, the code to create a List<ArrayList> would look something like this:
// creates an ArrayList that holds ArrayLists
List<ArrayList> allTheLists = new ArrayList<ArrayList>();
allTheLists.add(yourList1);
allTheLists.add(yourList2);
...
allTheLists.add(yourList9);
you can do like this as well
public static <T> List<List<T>> sort(List<List<T>> list) {
list.sort((xs1, xs2) -> xs1.size() - xs2.size());
return list;
}
The sort method that's available on a List needs a Comparator. That comparator can be created with the Comparator.comparing method, with additional special implementations including for extracting and comparing an int - Comparator.comparingInt.
import static java.util.Comparator.comparingInt;
...
List<List<Integer>> listOfLists = ...
listOfLists.sort(comparingInt(List::size));
List::size will map a List to an int (the size of the list) and use that to create a new Comparator that can be used for our sorting purposes.
If you want largest first
listOfLists.sort(comparingInt(List::size).reversed());
Dump the top 5 (switching over to Java 8 streams):
listOfLists.stream()
.sorted(comparingInt(List::size).reversed())
.limit(5)
.forEachOrdered(System.out::println);