So when I insert an Arraylist A into an Arraylist constructor I expect a new Arraylist object B created with the same set of objects as A. In my case I have
Arraylist<Arraylist<Integer>> powerSet
Arraylist<Arraylist<Integer>> OG
Both powerSet and OG seem to share the same reference despite OG being constructed from powerSet like this:
ArrayList<ArrayList<Integer>> OG = new ArrayList<>(powerSet);
Here is the full code:
public static ArrayList<ArrayList<Integer>> generatePower (ArrayList<Integer> s){
ArrayList<ArrayList<Integer>> powerSet = new ArrayList<>();
generatePower(s,powerSet);
return powerSet;
}
public static void generatePower(ArrayList<Integer> s,ArrayList<ArrayList<Integer>> powerSet ){
if(s.size()==0){
powerSet.add(s);
return;
}
else{
int temp = s.remove(0);
generatePower(s,powerSet);
ArrayList<ArrayList<Integer>> OG = new ArrayList<>(powerSet);
for(ArrayList<Integer> el: OG){
el.add(temp); //for some reason any changes I make to OG here is
//reflected in the powerSet
}
powerSet.addAll(OG);
}
}
Why do OG and powerSet have the same reference and how do I make OG be a new arraylist containing all of powerSet's elements without have OG share powerSet's reference
The ArrayList constructor doesn't clone elements; it just copies references over. Here's one way to make a deep copy using streams
List<List<Integer>> copy = powerSet.stream()
.map(ArrayList::new)
.collect(Collectors.toList());
ArrayList<ArrayList<Integer>> OG = new ArrayList<>(powerSet);
this line pass all elements (copy references) stored in powerSet to OG.
It's work in the same way like example:
List<User> usersList_1 = Arrays.asList(user1, user2, user3);
List<User> usersList_2 = new ArrayList(userList_1);
user1.setName("John");
userList_2.get(0).getName();
output: John
Related
I want to create one sorted list out of my original list - without the Collections.sort(list) call changing the original list. So that I have one list unsorted and one being sorted - out of the same list.
Take a look at this code:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
list.add(5);
list.add(8);
list.add(3);
list.add(6);
System.out.println("Before method list is");
System.out.println(list);
ArrayList<Integer> theReturnedList = sorted(list);
System.out.println("After it is");
System.out.println(list);
}
private static ArrayList<Integer> sorted(ArrayList<Integer> list){
ArrayList<Integer> returnList = list;
Collections.sort(returnList);
return returnList;
}
The list object gets sorted - even though I am not calling the Collection.sort() method onto it. How can I avoid it?
Beacuse I thought this would happen...
public static void main(String[] args) {
String original = "I am an object created in main";
String theChangedObject = change(original);
System.out.println(original);
}
private static String change(String string){
String changed = string;
changed = "I was changed";
return changed;
}
The object orginal stays the same.
Your problem is a misunderstanding of how references work. Let's take a look at the method:
private static ArrayList<Integer> sorted(ArrayList<Integer> list){
ArrayList<Integer> returnList = list;
Collections.sort(returnList);
return returnList;
}
The line ArrayList<Integer> returnList = list; does not copy the list. It copies the reference to the list. What this means is that returnList and list will both refer to the same list. Changes in one will affect the other, because they are actually just different names for the same thing.
What you want to do is to make a brand new list containing the same values, which can be done with
ArrayList<Integer> returnList = new ArrayList<>();
returnList.addAll(list);
There is also a convenient ArrayList constructor that does this in one step:
ArrayList<Integer> returnList = new ArrayList<>(list);
Changes to returnList will not affect list because they are now two completely independent lists that just happen to contain the same values.
In your sorted method you are still calling Collection.sort on the original list. To avoid this you could create a shallow copy and return that e.g.
private static ArrayList<Integer> sorted(ArrayList<Integer> list){
ArrayList<Integer> returnList = new ArrayList<>(list);
Collections.sort(returnList);
return returnList;
}
On this line:
ArrayList<Integer> returnList = list;
you are just creating another reference to the same list (Object) in your sorted method and any change that you apply to it using this new reference will be reflected in you original reference because they point to the same object. You can do this to create a new list:
private static ArrayList<Integer> sorted(ArrayList<Integer> list){
ArrayList<Integer> returnList = new ArrayList<>(list); // the new keyword creates a new object on the memory heap
Collections.sort(returnList);
return returnList;
}
This time we are creating another ArrayList Object with the elements of you original list. This way the original list won't change when you sort the newer.
This behaviour doesn't apply on Immutable Objects like String or LocalDateTime. These cannot change their state after being created and instead return a new copy with the changes applied.
you can use Stream api
List<Integer> list = Arrays.asList(5,8,3,6);
List<Integer> newList = list.stream().sorted().collect(Collectors.toList());
The stream api offers several methods to work with collections immutably. This is the recommended way if you are using Java 8 or later.
I want to know the shortcut for doing this :
class{ ArrayList a1=new ArrayList();
ArrayList a2=new ArrayList();
ArrayList a3=new ArrayList();
.....& so on
}
So instead of writing each reference, how can I write an array of references 'with ArrayList' ?
you can use `List<ArrayList> list = new ArrayList<ArrayList>();`. In this you can add any number of `ArrayList` Objects to `list` reference.
Find the below :
List<ArrayList> list = new ArrayList<ArrayList>();
list.add(new ArrayList());
list.add(new ArrayList());
list.add(new ArrayList());
list.add(new ArrayList());
// ....
list hold ArrayList references in inserted order. You can access the ArrayList using index which zero based.
// to access the ArrayList reference.
ArrayList a1 = list.get(0);
Use an array of ArrayList. And loop.
ArrayList a1, a2, ... , a100;
ArrayList[] arrayLists = new ArrayList[100];
for (ArrayList arrayList : arrayLists) {
arrayList = new ArrayList();
}
But creating different references array is not a good design.
For example you can create array list array like below:
ArrayList[] a = new ArrayList[4];
Before implementing this you clear with your requirement , why you need to create these many references.
And also while creating ArrayList it's better to use reference creation like below:
List<String> a = new ArrayList<String>();
Always use generics while working on JAVA collections.
For your requirement to store word and it's permutations, I would suggest below process:
Step1: Create WordPermutations class
public Class WordPermutations{
public string word;
public ArrayList<String> permutations = new ArrayList<String>();
public void setWord(String word){
this.word = word;
}
public void setPermutations(ArrayList<string> permutations){
this.permutations = permutations;
}
public String getWord(){
return this.word;
}
public ArrayList<String> getPermuatations(){
return this.permuations;
}
}
Step2: Use this class to create your arrayList objects like below:
Class MainPermutation{
public static void main(String args[]){
// your code to get all your words and their permutations
// Now add them like below
ArrayList<WordPermutations> words = new ArrayList<WordPermutations>();
//your loop to iterate words and their permutations
for (int i=0;i<words.length;i++){
WordPermutations wordP = new WordPermutations();
wordP.setWord(word); //String word
wordP.setPermutations(permutations); //arraylist of permutations
words.add(wordP); //adding your word and it's permutations to class
}
}
}
Step3: Now read your arrayList array accordingly
with above process you can store n number of words.
Hope it helps you.
What is the most efficient way to search for a single element in an ArrayList of ArrayLists? Given the following:
ArrayList<ArrayList<Integer>> intList = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> a = new ArrayList<>();
a.add(1);
a.add(2);
ArrayList<Integer> b = new ArrayList<>();
b.add(3);
b.add(4);
intList.add(a);
intList.add(b);
How would I search to see if the ArrayList intList contains a specific Integer, like 3?
Just iterates trough all the lists and ask if any of them contain your value.
public boolean contains(int x, ArrayList<ArrayList<Integer>> listOfLists) {
for (ArrayList list: listOfLists) {
if (list.contains(x)) return true;
}
return false;
}
However, I agree with radai. There is probably the need for a more efficient data structure rather than an efficient algorithm
I'm working with Depth First Search program and I'm trying to create a Adjacency List Representation.
I read through some articles stating that an creating ArrayLists within an ArrayList would be the best representation.
Let's say I initialized the arraylist within a arraylist like so:
List<List<Integer>> adjList = new ArrayList<List<Integer>>();
My question is how would you input data into the arraylist MANUALLY. I'm trying to understand the concept of arraylist with an arraylist before I begin my programming. If someone could possibly insert data into this arraylist so I could see the proper way of setting up.
Any additional input on anything I might need or take in consideration is recommended.
BTW: This is not a homework assignment just using personal time looking through my old textbooks.
Let's say you want to add 2 lists, one with 1 and 2 and the other with 10 and 20. A very manual way of adding could be:
List<List<Integer>> adjList = new ArrayList<List<Integer>>();
adjList.add(new ArrayList<Integer>()); // initialise new ArrayList<Integer>
adjList.get(0).add(1); // add value one by one
adjList.get(0).add(2);
adjList.add(new ArrayList<Integer>());
adjList.get(1).add(10);
adjList.get(1).add(20);
You could also write it this way:
List<List<Integer>> adjList = new ArrayList<List<Integer>>();
ArrayList<Integer> a1 = new ArrayList<Integer>(); // initialise new ArrayList<Integer>
a1.add(1); // add value one by one
a1.add(2);
adjList.add(a1);
ArrayList<Integer> a2 = new ArrayList<Integer>(); // initialise new ArrayList<Integer>
a2.add(10); // add value one by one
a2.add(20);
adjList.add(a2);
Well, a list of a list of Integer objects could be done as such:
List<List<Integer>> adjList = new ArrayList<List<Integer>>();
List<Integer> li = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
li.add(i);
}
adjList.add(li);
Add to each sublist, and then add the sublist.
The adjList can contain the elements of the type List<Integer>, so create one and add using add(E element) function as we would for adding an element:
ArrayList<Integer>aList = new ArrayList<>();
adjList.add(aList);
Then to add an element to the element(which has the type List<Integer>) of adjList: you can try getting it using get(index) and add your element:
adjList.get(0).add(10);
adjList.get(0).add(22);
Try adding a second list and get it's index using get(1) and add the Integer element to the list at index 1 as the above example suggest. There are other known function too. Please check the class ArrayList<E> documentation page.
This will help
public static void main(String[] args){
//creating a new ArrayList of List of Integers
ArrayList<List<Integer>> integerListContainer = new ArrayList<List<Integer>>();
//Creating the first child arraylist of Integers
ArrayList<Integer> firstChildintegerList = new ArrayList<Integer>();
//filling the values 1,2,3 in it
firstChildintegerList.add(1);
firstChildintegerList.add(2);
firstChildintegerList.add(3);
//adding this integer list to the parent list
integerListContainer.add(firstChildintegerList);
//Creating the second child arraylist of Integers
ArrayList<Integer> secondChildintegerList = new ArrayList<Integer>();
//filling the values 10,20,30 in it
secondChildintegerList.add(10);
secondChildintegerList.add(20);
secondChildintegerList.add(30);
//adding this integer list to the parent list
integerListContainer.add(secondChildintegerList);
System.out.println("Printing the parent list to see what it has: ");
System.out.println(integerListContainer.toString());
}
Hope it clearly explains what happens
I'm facing a problem when operating on an ArrayList of ArrayList in Java. I have this thing in my code-
ArrayList<ArrayList<Integer>> L1 = new ArrayList<ArrayList<Integer>>();
Problem is, I have no idea as to how I should operate on this (addition, removal, traversal etc.). I wish to create an adjacency list (for implementing simple, undirected graphs), and my instructor suggests that I should create an ArrayList of ArrayList. I know I can do the following to add new element-
L1.add(//Something I want to add);
But this throws up an error in the current case for obvious reasons.
An ArrayList of an ArrayList, just think that the outer object is an ArrayList and you are done.
ArrayList<ArrayList<Integer>> list2d = new ArrayList<ArrayList<Integer>>();
// add an element to the list
list2d.add(new ArrayList<Integer>());
// retrieve a list
ArrayList<Integer> list1d = list2d.get(0);
// add an integer
list2d.get(0).add(123);
By the way, an adjacency list is just a list of edges, there's no need to store them for each vertex, especially if the graph is undirected. A list of Edge would be enough:
class Edge {
Vertex v1, v2;
}
ArrayList<Edge> adjacencyList;
If you want to store them on a per vertex basis then you could avoid using a list of lists by encapsulating the edges inside the vertex class itself but this will require twice the edges:
class Vertex {
int value;
ArrayList<Vertex> adjacency;
}
but which one is best depends on what kind of operation you need to perform on the graph. For a small graph there is no practical difference.
Another possible implementation, if you just need to know if two vertex are connected:
class Edge {
public final int v1, v2;
public boolean equals(Object o) { return o != null && o instanceof Edge && o.hashCode() == hashCode(); }
public int hashCode() { return v1 ^ v2; } // simple hash code, could be more sophisticated
}
Set<Edge> adjacencyList = new HashSet<Edge>();
Try L1.get(i).add(whatever);, and of course first check whether L1.get(i) exists, otherwise add that inner list first.
It's something like this:
List<List<Integer>> L1 = new ArrayList<List<Integer>>(); //better use interfaces
List<Integer> first = null;
if( L1.size() > 0) {
first = L1.get(0); //first element
}
else {
first = new ArrayList<Integer>();
L1.add(first);
}
first.add(4711); //or whatever you like to add
List<List<Integer>> L1 = new ArrayList<ArrayList<Integer>>();
List<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
//add list to the list
L1.add(list1);
iterate over the list of lists
for( List<Integer> list: L1 ){
for(Integer i:list){
System.out.println(i);
}
}
You can only add objects of type ArrayList to L1. So you could do this:
ArrayList<ArrayList<Integer>> firstList = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> secondList = new ArrayList<Integer>();
secondList.add(0);
firstList.add(secondList);
L1.add(new ArrayList<Integer>());
will create a new List within the first list. Then you can
L1.get(0).add(5)
To add a new element to the outer array:
ArrayList<Integer> inner = new ArrayList<Integer>();
L1.add(inner);
Then to add element to the inner array:
int exampleInt = 10;
ArrayList<Integer> inner = L1.get(0);
inner.add(exampleInt);
To traverse all elements in all arrays:
for (ArrayList<Integer> inner : L1)
{
for (Integer element : inner)
{
System.out.println(element);
}
}