List of List but by output is not coming right - java

I have been trying to insert list of integer to another list but it seems i am making some mistake my output is not coming correct could anyone please help?
You can also comment http://goo.gl/xdLP9H
public class ListInsideList {
public static void main(String[] args) {
List<List<Integer>> newList = new ArrayList<List<Integer>>();
List<Integer> tempList = new ArrayList<Integer>();
List<Integer> originalList = new ArrayList<Integer>();
for (int i = 1; i <= 10; i++) {
originalList.add(i);//adding values to list
}
for(Integer value : originalList){
tempList.add(value);
if(tempList.size()==5)
{
newList.add(tempList);
System.out.println("iteration:"+newList);
tempList.clear();//clearing list
}
}
System.out.println("final:"+newList);
}
}
Output:
iteration:[[6, 7, 8, 9, 10], [6, 7, 8, 9, 10]]
final :[[], []]
required is:iteration:[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
final:[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]

Your final answer requires there be 2 separate lists.
[1, 2, 3, 4, 5] // List One
[6, 7, 8, 9, 10] // List Two
So where do you create these two separate lists? You don't, you're just re-using the same tempList on each iteration. Adding tempList to another List doesn't divorce it from the variable name of "tempList" which is a reference to the same object which you then clear().
Instead of clear(), create a new one each time:
Instead of tempList.clear(); //clearing list
Use tempList = new ArrayList<>(); // new List

You can replace newList.add(tempList); with:
1.
note: for this to work, your tempList must be a ArrayList (for List isn't serializable);
newList.add(SerializationUtils.clone(tempList));
templist.clear();
2.
List<Integer> list = new ArrayList<>(newList.size());
list.addAll(newList);
newList.add(list);
newList.clear();

Your Lists are empty in the final print statement. There is nothing for it to print since both the lists are empty as shown,
System.out.println("final:"+newList.get(0).isEmpty());
and
System.out.println("final:"+newList.get(1).isEmpty());
so instead try,
ArrayList<ArrayList<Integer>> newList = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> tempList = new ArrayList<Integer>();
ArrayList<Integer> originalList = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> finalList = new ArrayList<ArrayList<Integer>>();
for (int i = 1; i <= 10; i++) {
originalList.add(i);//adding values to list
}
for(Integer value : originalList){
tempList.add(value);
if(tempList.size()==5)
{
newList.add(tempList);
System.out.println("iteration:"+newList);
finalList = newList;
}
}
System.out.println("final:"+finalList);

you can do something like this for minimal workload:
change
newList.add(tempList)
to
newList.add(newArrayList<Integer>(tempList));
in order to copy tempList and not using it's reference
for(Integer value : originalList){
tempList.add(value);
if(tempList.size()==5)
{
newList.add(new ArrayList<Integer>(tempList));
System.out.println("iteration:"+newList);
tempList.clear();//clearing list
}
}
System.out.println("final:"+newList);

Related

Create a list of List from an Array

How can i create a list of List from Array eg:
int[] arr = {3, 1, 5, 8, 2, 4}.
Such that the lists in the List have only two elements eg:
[[3,1], [5,8], [2,4]].
So far i have tried code below but it return only lists with one element,I can't figure out where i went wrong.
class ListList {
public static List<List<Integer>> listOfList(int[] num){
List<List<Integer>> arrList = new ArrayList<>();
for(int i = 0 ; i<num.length;i++){
List<Integer> list = new ArrayList<>();
if(list.size() !=2){
list.add(num[i]);
}
arrList.add(list);
}
return arrList;
}
}
Result: [[3], [1], [5], [8], [2], [4]].
Here's a generic one:
var arr = new int[] {3, 1, 5, 8, 2, 4};
var batchSize = 2;
List<List<Integer>> lists = IntStream.range(0, arr.length)
.mapToObj(index -> Map.entry(index, arr[index]))
.collect(Collectors.groupingBy(e -> e.getKey() / batchSize))
.values().stream()
.map(entries -> entries.stream().map(Map.Entry::getValue).toList())
.toList();
System.out.println(lists);
Output:
[[3, 1], [5, 8], [2, 4]]
You are basically creating a mapping of index->value and subsequently grouping by the batchSize to make splits
You are creating an empty list on each iteration, then you check if its size != 2 (of course it is) and add 1 element, finally you add list with 1 element to result list, which is not what you need.
Move list creation out of loop and add elements to it. When its size == 2, add current list to result list and create a new one.
class ListList {
public static List<List<Integer>> listOfList(int[] num) {
List<List<Integer>> arrList = new ArrayList<>();
List<Integer> list = new ArrayList<>();
for(int i = 0; i < num.length; i++) {
if(list.size() == 2) {
arrList.add(list);
list = new ArrayList<>();
}
list.add(num[i]);
}
if(list.size() != 0) {
arrList.add(list);
}
return arrList;
}
}
If your input size can be odd, then you would also add list of length 1 to result list. If you don't want to, add aditional checks.
If you're certain that the list has an even number of values, you can do it like this.
create a list of lists.
taking two at a time, put each in a separate list
add that list to the list of lists
int [] arr ={3, 1, 5, 8, 2, 4};
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < arr.length; i+=2) {
List<Integer> temp = Arrays.asList(arr[i], arr[i+1]);
list.add(temp);
}
System.out.println(list);
prints
[[3, 1], [5, 8], [2, 4]]
If you list is of odd length, change the assignment to
List<Integer> temp = arr.length - i >= 2 ? Arrays.asList(arr[i], arr[i+1]) :
Arrays.asList(arr[i]);
And here is a different take on the idea suggested by Dhrubajyoti Gogoi.
stream the indices.
use integer math to divide into groups, mapping to a list
and return the values as a collection of lists.
int groupSize = 2;
Collection<List<Integer>> result =
IntStream.range(0, arr.length)
.mapToObj(Integer::valueOf)
.collect(Collectors.groupingBy(
i -> i / groupSize,
Collectors.mapping(i -> arr[i],
Collectors.toList())))
.values();
Try this:
public static List<List<Integer>> listOfList(int[] num){
List<List<Integer>> arrList = new ArrayList<>();
for (int i = 0; i < num.length; i += 2) {
if (num.length > i + 1) {
arrList.add(List.of(num[i], num[i+1]));
} else {
arrList.add(List.of(num[i]));
}
}
return arrList;
}
In your example you always create a fresh list in the loop, so size is always 0 and never 2.

How to create a new List from merging 3 ArrayLists in round robin style?

I have 3 arrays. I want to merge the 3 arrays and create a new array that shows all the merged integers. I would like this new array to be in round robin style.
Example input:
array = {arr1 = 1, 2, 3, arr2 = 4, 5, 6, arr3 = 7, 8, 9}
Example output:
arr4 = 1, 4, 7, 2, 5, 8, 3, 6, 9
I'm supposed to use this function but I don't understand how can I use a listOfLists:
String roundRobin(List<List<Integer>>listOfLists) {
You could do it more simply using ArrayLists or Arrays.
With Arrays, you create 3 int[] and 1 int[][].
What this translates to is "3 arrays of ints and 1 array of arrays of ints". That is what #4 is: an array of your other arrays. In code it is:
int[]
arr1 = {1, 2, 3},
arr2 = {4, 5, 6},
arr3 = {7, 8, 9};
int[][] arr4 = {arr1, arr2, arr3};
Alternatively, you could use ArrayLists, which differ from Arrays in that you can add or remove elements, among many other actions. The logic is the same in this case, just the syntax is different. You create 3 ArrayList<Integer> and 1 ArrayList<ArrayList<Integer>>, which translates to "3 ArrayLists of Integers and 1 ArrayList of ArrayLists of Integers." In code it is:
ArrayList<Integer>
list1 = new ArrayList<>(Arrays.asList(1, 2, 3)),
list2 = new ArrayList<>(Arrays.asList(4, 5, 6)),
list3 = new ArrayList<>(Arrays.asList(7, 8, 9));
List<ArrayList<Integer>> list4 = new ArrayList<>
(Arrays.asList(list1, list2, list3));
Finally, you can print the output of both methods:
System.out.println("Arrays - int[][]: " + Arrays.deepToString(arr4)
+ "\nLists - List<ArrayList<Integer>>: " + list4);
And you will get:
Arrays - int[][]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Lists - List<List<Integer>>: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Does this help?
You can use two nested for loops:
List<List<Integer>> lists = List.of(
List.of(1, 2),
List.of(3, 4, 5, 6),
List.of(7, 8, 9));
List<Integer> listRobin = new ArrayList<>();
// infinite loop through the columns
for (int i = 0; ; i++) {
// if the maximum number
// of columns is reached
boolean max = true;
// loop through the rows, aka inner lists
for (List<Integer> row : lists) {
// if this column is present
if (i < row.size()) {
// column is present
max = false;
// take value from the column
listRobin.add(row.get(i));
}
}
// while the columns are still present
if (max) break;
}
// output
System.out.println(listRobin);
// [1, 3, 7, 2, 4, 8, 5, 9, 6]
See also: Filling a jagged 2d array first by columns
I think just loop input and get element and add element to a list of array is easy to understand.
public static List<Integer> roundRobin(List<List<Integer>> listOfLists) {
if (listOfLists == null || listOfLists.isEmpty()) {
return new ArrayList<>();
}
int maxLength = -1;
for (List<Integer> list : listOfLists) {
if (list.size() > maxLength) {
maxLength = list.size();
}
}
List<Integer> result = new ArrayList<>(maxLength * listOfLists.size());
for (int i = 0; i < maxLength; i++) {
for (List<Integer> list : listOfLists) {
if (i < list.size()) {
result.add(list.get(i));
}
}
}
return result;
}
To populate a 1d list from the columns of a 2d list, you can use two nested streams: first by columns, and then by rows. The length of the internal lists does not matter, in an outer stream you can traverse while the columns are still present.
List<List<Integer>> listOfLists = List.of(
List.of(1, 2, 3, 4),
List.of(5, 6),
List.of(7, 8, 9));
List<Integer> listRobin = IntStream
// infinite Stream through
// the columns of a 2d list
.iterate(0, i -> i + 1)
// take the values from the column
// Stream<List<Integer>>
.mapToObj(i -> listOfLists
// iterate over the inner lists
.stream()
// take those lists where
// this column is present
.filter(list -> list.size() > i)
// take value from the column
.map(list -> list.get(i))
// return a new list
.collect(Collectors.toList()))
// while the columns are still present
.takeWhile(list -> list.size() > 0)
// flatten to a single stream
// Stream<Integer>
.flatMap(List::stream)
// return a new list
.collect(Collectors.toList());
// output
System.out.print(listRobin); // [1, 5, 7, 2, 6, 8, 3, 9, 4]
See also: Efficient way to choose data from several Lists with round robin algorithm

ANDROID how to filter a list base on another list in kotlin/java?

I have two lists:
list_1 = [1, 2, 3, 4, 5]
list_2 = [1, 3, 5, 6, 7]
I want to get a list like this:
list_3 = [1, 2, 3, 4, 5, 6, 7]
No need to sort in ascending order, Thanks.
You can do something like this following by using union operator
fun temp()
{
val firstList = arrayListOf(1,2,3,4,5)
val secondList = arrayListOf(1,3,5,6,7)
val finalList = firstList.union(secondList)
println("First list : ${firstList}")
println("Second list : ${secondList}")
println("Final list : ${finalList}")
}
InsecondList contains common elements 1,3 and 5 as the firstList, It was removed in the finalList. You can also use distinct operator according to your needs.
If I understand correctly, you want entries from both lists, but they must appear only once. I assume from your last statement that the order does not matter. In that case this would be perfect for a Set. A Set is a Collection, so you can iterate through all the elements just as, for example, with a List.
EDIT
Code snippets:
Integer[] a = {1,2,3};
Integer[] b = {2,3,4};
Set<Integer> s = new HashSet<>();
s.addAll(Arrays.asList(a));
s.addAll(Arrays.asList(b));
for (int i : s) {
System.out.print(i + ", ");
}
System.out.println();
If your integers are already in a primitive array:
int[] c = {1,2,3};
int[] d = {2,3,4};
Set<Integer> S = new HashSet<>();
S.addAll(Arrays.asList(Arrays.stream(c).boxed().toArray(Integer[]::new)));
S.addAll(Arrays.asList(Arrays.stream(d).boxed().toArray(Integer[]::new)));
for (int i : S) {
System.out.print(i + ", ");
}
System.out.println();
For both of these the output is:
1, 2, 3, 4,

ArrayList inside an ArrayList is getting overridden

Here is my code.
In my case list is getting over ridden.
output should be [[1][1,1][1,2,1][1,3,3,1][1,4,6,4,1]
I am getting like - [[1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1], [1, 4, 6, 4, 1]]. which is latest value in the loop repeated. what might be the problem
int i,j;
i=0;
j=0;
int a;
Integer temp;
a = 5;
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> list1 = new ArrayList<Integer>();
for ( i =0 ;i<a ;i++)
{
list1.clear();
Integer number;
number = (int) Math.pow(11, i);
LinkedList<Integer> stack = new LinkedList<Integer>();
while (number > 0) {
stack.push( number % 10 );
number = number / 10;
}
while (!stack.isEmpty()) {
temp = (stack.pop());
list1.add(temp);
}
list.add(list1);
}
System.out.println("The arraylist contains the following elements: "+ list);
It seems like you are cleaning your List1 array every time. And you have only one array list inside large array list. So you end up with the last results you put on inner arraylist. To get expected results, you shoud create several arraylists inside the for loop.
Replace list1.clear() with list1 = new ArrayList<Integer>();
In Java it is call by value. But when say list1 you only have the reference to list1.
So when you are iterating, you are doing list1.clear. What it does it clears the list pointed to by the reference list1. This will clear the list that you added into the list. So what you get at the end is the latest content of list1.
For a detailed understanding, refer to this

A List, anyone can answer

public static void main(String[] args) {
List<List<Integer>> list = new ArrayList<List<Integer>>(); // final list
List<Integer> l = new ArrayList<Integer>(); // l is list
List<Integer> m = new ArrayList<Integer>(); // m is list
List<Integer> temp = new ArrayList<Integer>();
l.add(1);
l.add(2);
l.add(3); // list l
m.add(4);
m.add(5);
m.add(6); // list m
temp.addAll(l); // add l to temp
list.add(temp);
System.out.println("temp: "+temp);
System.out.println("list: "+list);
temp.addAll(m); // add m to temp1
list.add(temp);
System.out.println("temp: "+temp);
System.out.println("list: "+list);
}
the result is
temp: [1, 2, 3]
list: [[1, 2, 3]]
temp: [1, 2, 3, 4, 5, 6]
list: [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]]
I think it should be:
temp: [1, 2, 3]
list: [[1, 2, 3]]
temp: [1, 2, 3, 4, 5, 6]
list: [[1, 2, 3], [1, 2, 3, 4, 5, 6]]
why the last list is [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]]?
I rename your temp1 to temp in order to get compiled correctly.
This is because when you first execute "list.add(temp);"
list gets a reference to temp. So when the content of temp is changed, the content of list also gets changed.
public static void main(String[] args) {
List<List<Integer>> list = new ArrayList<List<Integer>>(); // final list
List<Integer> l = new ArrayList<Integer>(); // l is list
List<Integer> m = new ArrayList<Integer>(); // m is list
List<Integer> temp = new ArrayList<Integer>();
l.add(1);
l.add(2);
l.add(3); // list l
m.add(4);
m.add(5);
m.add(6); // list m
temp.addAll(l); // add l to temp1
list.add(temp); // list now references to temp. So when the content of temp is changed, the content of list also gets changed.
System.out.println("temp: "+temp);
System.out.println("list: "+list);
temp.addAll(m); // add m to temp. The content of temp is changed, so does the content of list
list.add(temp);
System.out.println("temp: "+temp);
System.out.println("list: "+list);
}
The list list ends up with two references to the same list (temp). You can achieve the desired behavior by creating a second temporary list, adding the contents of temp to it, then adding 4, 5, and 6 to it, then adding that temporary list to list.
I assume there is no temp1 variable in the code, it is the same as temp.
You are surprised by the fact that after adding "temp" to the "list" in the first time, the content of this first element was changed when you change temp. What you are missing is that "list" is an list of references, so its first element is a reference to "temp", not a copy of its content. Hence, whenever "temp" changes, this will be reported in the printout, even if the content of ""list" is not changed.
You can examine this behavior by adding something, say "100" to temp "just before printing, without changing "list". You will see that 100 will appear in the printout.

Categories