Adding a array list to arraylist - java

import java.util.*;
class test2{
static void fun(int i,int arr[],List<Integer> l,int n,List<List<Integer>> res){
if(i==n){
if(l.size()!=0){
//System.out.println(l.size());
res.add((l));
//System.out.println(res);
}
//System.out.println(l);
return;
}
l.add(arr[i]);
fun(i+1,arr,l,n,res);
//System.out.println(l);
l.remove(l.size()-1);
//System.out.println(l);
fun(i+1,arr,l,n,res);
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int arr[]=new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
List<Integer> l=new ArrayList<>();
List<List<Integer>> res=new ArrayList<>();
fun(0,arr,l,n,res);
System.out.println(res);
}
}
in fun function while i am adding a List to other List it is adding empty list i could find the reason can somebody help me this program is about finding the different combinations of given array

You can use res.add((new ArrayList<>(l)) instead of res.add((l)).
Why should use (new ArrayList<>(existing_list))?
When you update any primitive value then put in a list you can update again that primivite value. That does not change the value in list. But an object does not work like that. Well we can say it causes kind of pointer. When you update an object then it updates the values in its address. Let me show you a short example.
public class MyObject {
private List<String> list = new ArrayList<>();
public MyObject() {
list.add("added in Constructor");
}
public List getList() {
return list;
}
}
public static void main(String[] args) {
MyObject myObject = new MyObject();
System.out.println("--> Object list (Before added anything in main) : ");
myObject.getList().forEach(System.out::println);
List list = myObject.getList();
list.add("added in Main");
System.out.println("--> local list : ");
list.forEach(System.out::println);
System.out.println("--> Object list (After added a value in main) : ");
myObject.getList().forEach(System.out::println);
}
And the ouput is :
--> Object list (Before added anything in main) :
added in Constructor
--> local list :
added in Constructor
added in Main
--> Object list (After added a value in main) :
added in Constructor
added in Main
I did not set up a new Arraylist or create new one but my private list in MyObject is updated even if I just do changes in main function.
But instead of list If I returned new Array<>(list) then even if I update the list in main, my list would never change. Because I return another address with new Array<>(list). So you should add your list with another addres. I mean another Arraylist. So you can use res.add((new ArrayList<>(l)) instead of res.add((l)).

Related

Why changes in sublist are reflected in the original list in Java... how to avoid this?

// "static void main" must be defined in a public class.
import java.util.*;
public class Main {
static void func(ArrayList<ArrayList<Integer>> arr) {
ArrayList<Integer> arr1 = new ArrayList();
arr1.add(0);
arr.add(arr1);
arr1.set(0,5);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
func(arr);
for(int i=0;i<arr.size();i++) {
for(int j=0;j<arr.get(i).size();j++) {
System.out.print(arr.get(i).get(j));
}
System.out.println();
}
}
}
In the above code, we add an 1D arraylist of 1 element (0) to the 2D arraylist arr, but when we change the value in the 1D arraylist from 0 to 5, why is the same change reflected in the 2d arraylist, and most importantly, how exactly do we avoid this?
By default, Java Lists are mutable and you can easily change their content by adding or removing elements. In addition to this, your arr List has a reference to arr1 and not a copy of it. This means that whenever you change 1D this change is also reflected in arr because both arr1 and the content of arr reference to the same exact List.
One way to avoid this is actually copying the arr1 List before adding it to arr as follows:
static void func(ArrayList<ArrayList<Integer>> arr) {
ArrayList<Integer> arr1 = new ArrayList<>();
arr1.add(0);
arr.add(new ArrayList<>(arr1));
arr1.set(0,5);
}
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
func(arr);
for(int i=0;i<arr.size();i++) {
for(int j=0;j<arr.get(i).size();j++) {
System.out.print(arr.get(i).get(j));
}
System.out.println();
}
}
Mind the changed line arr.add(new ArrayList<>(arr1));. This guarantees that the reference that arr holds is different than the reference of the original arr1. You are basically creating a new List.
Although this fixes your case, it might not work for every List because it depends on its content. This works on your case because Integer is an immutable class, but if you would have a List of a mutable class, then this wouldn't be enough because both Lists would reference exactly the same objects. An example of this is below:
public static void main(String[] args) {
ArrayList<ArrayList<MutableClass>> arr = new ArrayList<>();
ArrayList<MutableClass> arr1 = new ArrayList<>();
arr1.add(new MutableClass("original"));
arr.add(new ArrayList<>(arr1));
System.out.println(arr.get(0));
// now let's change the property of arr1 MutableClass to something else
arr1.get(0).setProperty("changed");
System.out.println(arr.get(0));
}
public static class MutableClass {
private String property;
public MutableClass(String property) {
this.property = property;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
#Override
public String toString() {
return "MutableClass{" +
"property='" + property + '\'' +
'}';
}
}
As you can see by running the code, changing the object in arr1, also changes the object in arr even if you create a new List. The only way to overcome this is by making MutableClass immutable or by deep copying the original arr1 List before adding it to arr. This means you would need to copy every single object inside arr1 as follows:
public static void main(String[] args) {
ArrayList<ArrayList<MutableClass>> arr = new ArrayList<>();
ArrayList<MutableClass> arr1 = new ArrayList<>();
arr1.add(new MutableClass("original"));
ArrayList<MutableClass> copiedList = new ArrayList<>();
for (MutableClass object : arr1) {
copiedList.add(new MutableClass(object));
}
arr.add(copiedList);
System.out.println(arr.get(0));
// now let's change the property of arr1 MutableClass to something else
arr1.get(0).setProperty("changed");
System.out.println(arr.get(0));
}
public static class MutableClass {
private String property;
public MutableClass(String property) {
this.property = property;
}
public MutableClass(MutableClass other) {
this.property = other.property;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
#Override
public String toString() {
return "MutableClass{" +
"property='" + property + '\'' +
'}';
}
}
To avoid 5 getting reflected in 2D list
create a new array list from arr1 in method func() and add it to arr(the 2D list) as shown below.
static void func(ArrayList<ArrayList<Integer>> arr) {
ArrayList<Integer> arr1 = new ArrayList();
arr1.add(0);
arr.add(new ArrayList<>(arr1));
arr1.set(0,5);
}
The reason for the behaviour:
Java is pass by value
When we do
func(arr);
in main method, the reference to the actual array list object in heap is passed as value to the method "func()".
Inside func, hence arr will be pointing to the same object.
When we add the array list newly created arr1 into arr, the reference to actual object corresponding to arr1 gets added to the actual 2D array.
This is because both arr of func() as well as arr of main() refers to same object in heap.
When we try to change something in arr1 list,
it is referenced by arr. So, it will be still visible to arr.
Printing the list in main gives output 5.
But when we create a new array list and add that to arr in func(), as below
arr.add(new ArrayList<>(arr1));
then the list got added to arr will be different from arr1.
Hence,
while printing in main(),
the 2D list holds the reference to newly created array list
(ie; new ArrayList<>(arr1)).
So, it will not get affected by changing to 5 by the line
arr1.set(0,5);
This will still give 0 while printing the list arr in main().

How peek and map works in streams

I am trying to understand how different peek and map in java 8 streams.I have tried the following
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("A");
arr.add("B");
List<String> a = arr.stream().peek(t->t.toLowerCase()).collect(Collectors.toList());
System.out.println(a);
}
The above code is not changing the alphabets to lower case.But when i try the following
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("A");
arr.add("B");
List<String> a = arr.stream().map(t->t.toLowerCase()).collect(Collectors.toList());
System.out.println(a);
}
The alphabets are converted to smaller case.My doubt here is if i use both map and peek like below
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("A");
arr.add("B");
List<String> a = arr.stream().map(t->t.toLowerCase()).peek(t->toUpper()).collect(Collectors.toList());
System.out.println(a);
}
public static Function<String, String> toUpper(){
return t->{
return t.toUpperCase();
};
}
The map method converts A,B to lower and Peek does nothing.So if there is any calculation involved while streaming cant i make use of peek?Can someone explain
MOdified code
static List<Employee> e = new ArrayList<>();
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("Pavan");
arr.add("Kumar");
System.out.println("Size of emp"+e.size());
List<String> a = arr.stream().map(t->t.toLowerCase()).peek(t->populateEmp()).collect(Collectors.toList());
System.out.println("Size of emp"+e.size());
System.out.println(a);
}
public static Function<String, Employee> populateEmp(){
Employee ee = new Employee();
return t->{
System.out.println(t);
ee.setName(t);
e.add(ee);
return ee;
};
}
This is still not adding the Emp to list
Peek expects a Consumer, so if you are using toLowerCase() you are creating a new String, which is put into void. You may modify this object inside of a consumer, but String is immutable, so peek has no effect.
When you use map, then you expect to pass a Function or UnaryOperator, that receives single object and returns single object. So new String that is lower-cased is returned.
In both cases, objects are not cloned. So you could modify an object that is mutable inside of a peek function, but that is just the wrong way to do it:) Try passing a Date, then you can set hours inside a peek function because it's mutable.
In short:
use map to transform model to another model
use peek, to do something that consumes this object, but does not modify it (send a notification, print model, etc)
UPDATE:
public static Function<String, Employee> populateEmp(){
Employee ee = new Employee();
System.out.print("I am executed");
return t->{
System.out.print("I am not");
return null;
};
}
Try with this code. In your update, you are passing a consumer, that ignores passed argument, and you execute populateEmp() method, which returns a function, that adds to a map transformed object. But you NEVER execute this function, tus-> list is empty:)
In non-lambda word it looks like this:
for(String value: arr){
populateEmp(); // execute method but you do nothing with this Function.
}
So replace your peek with this:
.peek(t->populateEmp().apply(t))

ArrayList constructor and use in methods

Hi I am a novice n just learning java. I was studying ArrayList n came accross this code for example {CODE1}.
I would like to use the same code but add a ArrayListDemo constructor n create methods such as displayList and removeElement.
I tried to find such examples but i did not understand them.
This is the code that i tried {CODE2} With my modifications please tell me where m going wrong.
***CODE1 {Example Code}****
import java.util.ArrayList;
public class AraryListDemo {
public static void main(String[] args) {
ArrayList al = new ArrayList();
System.out.print("Initial size of al : " + al.size());
System.out.print("\n");
//add.elements to the array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1,"A2");//inserts objects "A2" into array at index 1
System.out.print("size of al after additions " + al.size());
System.out.print("\n");
//display the array list
System.out.print("contents of al: " + al );
System.out.print("\n");
//Remove elements from the array list
al.remove("F");
al.remove(2);
System.out.print("size of after deletions : " + al.size());
System.out.print("\n");
System.out.print("contents of al:" + al);
}
}
********CODE 2 {My Modifications}*************
class ArrayListDemo
{
ArrayList<String> al;//variable declared
ArrayListDemo() throws IOException//try constructor for this
{
al = new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("\n Enter Student Names");
for(int i=0;i<=5;i++)// will dispaly
{
al.add(br.readLine());
}
}
void dispList(ArrayList <String> al)
{
System.out.println("\n Display Student Names");
for(String str : al)
{
System.out.println("\t Name : "+str+"\n");
}
}
}
class DisplayArrayList
{
public static void main(String []args) throws IOException
{
ArrayList <String> al = new ArrayList <String>();
ArrayListDemo e = new ArrayListDemo();
e.dispList(al);
}
}
ArrayList <String> al = new ArrayList <String>();
ArrayListDemo e = new ArrayListDemo();
e.dispList(al);
In the above code, you are creating a new ArrayList al, and passing the same to dispList() method, which doesn't iterate, because the al has no elements.
I guess you wanted to iterate through the elements which you created within ArrayListDemo. So you may want to write dispList() method as below, which will now use ArrayList defined within the class
void dispList() //method parameter "al" is removed now and, al is the al of ArrayListDemo
{
System.out.println("\n Display Student Names");
for(String str : al) //here al refers to ArrayList defined within the class
{
System.out.println("\t Name : "+str+"\n");
}
}
It's not clear what exactly you're asking, but I note that you have a problem with your declarations (plural) of al: You have one ArrayList named al in your main, and you have another one that belongs to ArrayListDemo. You're reading values into the second one and then printing out the (empty) first one.
You really don't need a separate class with a constructor here. You can just have two static methods readList(List<String> al) and dispList(List<String> al). If you really do want to have a separate class, pick one place to store the List (either in main or in the class).
As a note, it's generally a good idea to use the most general type for variables and method parameters that you can. You're declaring an ArrayList, which is fine, but if you make your variable and parameters Lists, your code is more flexible.
The easiest (but not a prefered) solution to make your effort work is to pass the array to the displist() method that was filled by the constructor.
public static void main(String []args) throws IOException
{
ArrayListDemo e = new ArrayListDemo();
e.dispList(e.al);
}
Your code runs as following :-
ArrayList <String> al = new ArrayList <String>(); // Initialise an ArrayList of type string
ArrayListDemo e = new ArrayListDemo(); // Initialised class ArrayListDemo
class constructor reads data from user input and add to ArrayList a1 by br.readLine()
e.dispList(al); iterates the ArrayList instance a1 and print its output.

how can we access individual int value from LinkedHashset<set<Integer>? Through string is it possible

I want to remove duplicates e.g.{ {1,2,3}, {2,3,1},{3,2,1},{2,1,3} } are duplicates of {2,3,1} or any one from given 4 sets.for this i converted 2D Integer array into LinkedHashSet which removed duplicates but when i am converting back to array (due to need in algorithm) i am unable to access individual elements.is it possible? if not, what is the other way.if yes what is problem in the code.given below.please resolve.
my own other thinking: as i think through string is it possible?
e.g { {2,3,1},{-3,-2,-4},........... } insert in Set making ArrayList of each 3 element set e.g.{2,3,1},{-3,-2,-4},{3 element}, .....and then parseInt to access individual element as {2},{3},{1},{-3},{-2},{-4},... will it work?
import java.util.*;
class demo
{
Integer[][] orderedpair3k={{1,2,3},{1,3,-2},{2,3,-1},{1,2,3},{1,-3,-2},{2,-3,-1},{1,-2,-3},{1,3,2},{-2,3,-1},{1,-2,3},{1,-3,2},{-2,-3,-1}};
Set<Set<Integer>> r = new LinkedHashSet<Set<Integer>>();
Object[][] a;
public void init_clauses()
{
removeDuplicate();
System.out.println(r);
backToArray();
for(int i=0;i<a.length;i++)
System.out.println(a[0][i]);
}
public void removeDuplicate()
{
int i=orderedpair3k.length;
for(int j=0;j<i;j++)
r.add(new LinkedHashSet<Integer>(Arrays.asList(orderedpair3k[j])));
}
public void backToArray()
{
ArrayList<Set<Integer>> arr=new ArrayList<Set<Integer>>(r);
a = new Object[arr.size()][3];
for(int i=0;i<a.length;i++)
a[i]=arr.toArray(new Object[i]);
}
}
public class sat
{
public static void main(String[] arg){
demo S = new demo();
S.init_clauses();}
}
//in the above code i am unable to access individual element because in the array Set is inserted as Object even i tried using ((Integer)a[i][j]).intValue() i think this is due to Arrays.asList(orderedpair3k[j]) how this problem can be resolve?
Seems quite straightforward:
Integer[][] result = new Integer[r.size()][3];
int c = o;
for (Set<Integer> s : r)
result[c++] = s.toArray(new Integer[3]);

transfer arraylist to double array[0] in java

i have this code:
public class Test{
arrayList<String> list = new ArrayList<String>();
String[][] temp_list;
public static void main(String[] args)
{
String temp = list.get(0);
temp_list[0] = temp.split(" ");
}
}
i want to transfer the first item in 'list' into temp_list[0].compiling is success but i got error when i run it.this is the error:
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:this line=>temp_list[0] = temp.split(" ");)
anyone can help me?
This is because you haven't allocated any 2D-array for temp_list. (Which array should the result of split be stored in?)
Here's a working version of your snippet.
import java.util.ArrayList;
public class Test {
static ArrayList<String> list = new ArrayList<String>();
static String[][] temp_list;
public static void main(String[] args) {
list.add("hello wold");
// allocate memory for 10 string-arrays.
temp_list = new String[10][]; <-----------
String temp = list.get(0);
temp_list[0] = temp.split(" ");
}
}
This code would will not compile since list is declared as a member variable of the class but main is a static method.
As written, list has nothing added too so the call to list.get(0) will throw an Exception (not null pointer though).
The array temp_list is not allocated (no new) in the code given so trying assign into it will throw a null pointer exception.
You need to initialize temp_list before you use it. You need to specify the size of the array. For example:
int sizeOfArray = 5;
String[][] temp_list = new String[sizeOfArray][];

Categories

Resources