When a variable added into an ArrayList changes, does ArrayList update on its own? - arraylist

private static ArrayList<ArrayList<Integer>> listlist = new ArrayList<ArrayList<Integer>>();
private static ArrayList<Integer> list = new ArrayList<Integer>();
private static ArrayList<Integer> temp = new ArrayList<Integer>();
public static void main(String args[]) {
list.add(10);
list.add(20);
listlist.add(list);
temp = list;
temp.add(30);
listlist.set(0,temp);
System.out.println("size before temp is cleared: " + listlist.get(0).size());
temp.clear();
System.out.println("size after temp is cleared: " + listlist.get(0).size());
}
Output:
size before temp is cleared: 3
size after temp is cleared: 0
Here is a simplified portion of my code that is causing the problem. You can see how temp is being added to the listlist, and when temp is cleared after that action, the listlist seems to update itself and clear its contents in index 0 as well.
Is it true that the ArrayList updates itself whenever a variable used to insert a value is changed? Help needed.

The arrayList will keep references to the things you give it. In your case, temp and list are both references to the same object (So there is no need to do the set in listlist). When you do temp.clear, the list object referenced by "temp" and "list" (Which is the same) gets cleared. Your list of lists keeps a reference to that same object. It's not "updating itself automatically". It doesnt need to, it never made a copy. Im attaching a diagram that might help you understand. The circles represent objects. the arrows mean that a reference exists to the object being pointed (Either contained in another obect or its yours and i wrote the name/identifier)

Related

gtk#: Tree View object always passed as call-by-reference

It seems as if my arguments in the method call of processing a Tree View is always done as call-by-reference.
I have a visible GTK "Tree View" control on a top level window. The data was written by the respective model.
Now I want to remove some of the columns (based on options set by the user) and pass the manipulated Tree View to an Export-Function.
In order to remove the columns only from the output, not from the GUI itself, I thought of copying the visible Tree View control into a temporary one, manipulating the temportary one and calling the export-functionality on the temporary one.
My problem is: even though I pass my origin, visible Tree View as referenc-by-value (as of my understanding), the origin will be manipulated and the removing of columns will be done on the visual Tree View.
It seem as if my arguments in the method call is always done as call-by-reference.
Code:
"treeview1" is the visual Gtk.Tree View...
I call my Export-function:
...
TreeView treeviewExport = SetExportViewAccordingToCheckboxes(treeview1);
ExportFile(treeviewExport);
...
In the method SetExportViewAccordingToCheckboxes() I just pass the global treeview1 as call-by-value, manipulate it internally and return the manipulated Tree View:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource)
{
TreeView tvRet = tvSource;
if (cbName == false)
tvRet.RemoveColumn( ... );
...
return tvRet;
}
But even though I have removed the columns from the internal Tree View "tvRet", my visual control "treeview1" lacks all the columns which were removed from "tvRet"; it looks like "treeview1" was passed as call-by-reference.
Question: why is that?
Note: I also tried with the keyword "in" which made no difference:
protected static TreeView SetExportViewAccordingToCheckboxes(in TreeView p_tvSource)
The problem comes here:
In the method SetExportViewAccordingToCheckboxes() I just pass the
global treeview1 as call-by-value, manipulate it internally and return
the manipulated Tree View:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource)
{
TreeView tvRet = tvSource;
if (cbName == false)
tvRet.RemoveColumn( ... );
...
return tvRet;
}
First some background. In C# terminology, value types are those that directly contain a value, while reference types are those that reference the data, instead of holding it directly.
So, int x = 5 means that you are creating the value object 5 of type integer, and storing it in x, while TreeView tree = new TreeView() means that you are creating a reference tree of type TreeView, which points to an object of the same type.
All of this means that you cannot pass an object by value, even if you want to. In the best case, you are passing the reference by value, which has no effect.
So, the next step is to copy the data, and modify the copied object instead of the original one. This is theoretically sound, but the line: TreeView tvRet = tvSource; unfortunately does not achieve that. You are creating a new reference, yes, but that reference points to the same object the original reference points to.
Now, say that we are managing objects of class Point instead of TreeView, with properties x and y.
class Point {
public int X { get; set; }
public int Y { get; set; }
}
You can create a point easily:
Point p1 = new Point { X = 5, Y = 7 };
But this does not copy it:
Point p2 = p1;
This would do:
Point p2 = new Point { X = p1.X, Y = p1.Y };
Now the original problem was that you wanted to pass a few columns to an Export() function. In that case, you only need to pass a vector of the filtered columns to the exporting function, instead of a copy of the TreeView.
void PrepareExporting()
{
var columns = new List<TreeViewColumn>();
foreach(TreeViewColumn col in this.treeView.Columns) {
if ( this.Filter( col ) ) {
columns.add( col );
}
}
this.Export( columns.ToArray() );
}
void Export(TreeViewColumn[] columns)
{
// ...
}
I think that would be easier, since it is not needed to try to achieve a pass-by-reference (impossible), nor copy the tree view.
Hope this helps.

Java 8 map with Map.get nullPointer Optimization

public class StartObject{
private Something something;
private Set<ObjectThatMatters> objectThatMattersSet;
}
public class Something{
private Set<SomeObject> someObjecSet;
}
public class SomeObject {
private AnotherObject anotherObjectSet;
}
public class AnotherObject{
private Set<ObjectThatMatters> objectThatMattersSet;
}
public class ObjectThatMatters{
private Long id;
}
private void someMethod(StartObject startObject) {
Map<Long, ObjectThatMatters> objectThatMattersMap = StartObject.getSomething()
.getSomeObject.stream()
.map(getSomeObject::getAnotherObject)
.flatMap(anotherObject-> anotherObject.getObjectThatMattersSet().stream())
.collect(Collectors.toMap(ObjectThatMatters -> ObjectThatMatters.getId(), Function.identity()));
Set<ObjectThatMatters > dbObjectThatMatters = new HashSet<>();
try {
dbObjectThatMatters.addAll( tartObject.getObjectThatMatters().stream().map(objectThatMatters-> objectThatMattersMap .get(objectThatMatters.getId())).collect(Collectors.toSet()));
} catch (NullPointerException e) {
throw new someCustomException();
}
startObject.setObjectThatMattersSet(dbObjectThatMatters);
Given a StartObject that contains a set of ObjectThatMatters
And a Something that contains the database structure already fetched filled with all valid ObjectThatMatters.
When I want to swap the StartObject set of ObjectThatMatters to the valid corresponding db objects that only exist in the scope of the Something
Then I compare the set of ObjectThatMatters on the StartObject
And replace every one of them with the valid ObjectThatMatters inside the Something object
And If some ObjectThatMatters doesn't have a valid ObjectThatMatters I throw a someCustomException
This someMethod seems pretty horrible, how can I make it more readable?
Already tried to change the try Catch to a optional but that doesn't actually help.
Used a Map instead of a List with List.contains because of performance, was this a good idea? The total number of ObjectThatMatters will be usually 500.
I'm not allowed to change the other classes structure and I'm only showing you the fields that affect this method not every field since they are extremely rich objects.
You don’t need a mapping step at all. The first operation, which produces a Map, can be used to produce the desired Set in the first place. Since there might be more objects than you are interested in, you may perform a filter operation.
So first, collect the IDs of the desired objects into a set, then collect the corresponding db objects, filtering by the Set of IDs. You can verify whether all IDs have been found, by comparing the resulting Set’s size with the ID Set’s size.
private void someMethod(StartObject startObject) {
Set<Long> id = startObject.getObjectThatMatters().stream()
.map(ObjectThatMatters::getId).collect(Collectors.toSet());
HashSet<ObjectThatMatters> objectThatMattersSet =
startObject.getSomething().getSomeObject().stream()
.flatMap(so -> so.getAnotherObject().getObjectThatMattersSet().stream())
.filter(obj -> id.contains(obj.getId()))
.collect(Collectors.toCollection(HashSet::new));
if(objectThatMattersSet.size() != id.size())
throw new SomeCustomException();
startObject.setObjectThatMattersSet(objectThatMattersSet);
}
This code produces a HashSet; if this is not a requirement, you can just use Collectors.toSet() to get an arbitrary Set implementation.
It’s even easy to find out which IDs were missing:
private void someMethod(StartObject startObject) {
Set<Long> id = startObject.getObjectThatMatters().stream()
.map(ObjectThatMatters::getId)
.collect(Collectors.toCollection(HashSet::new));// ensure mutable Set
HashSet<ObjectThatMatters> objectThatMattersSet =
startObject.getSomething().getSomeObject().stream()
.flatMap(so -> so.getAnotherObject().getObjectThatMattersSet().stream())
.filter(obj -> id.contains(obj.getId()))
.collect(Collectors.toCollection(HashSet::new));
if(objectThatMattersSet.size() != id.size()) {
objectThatMattersSet.stream().map(ObjectThatMatters::getId).forEach(id::remove);
throw new SomeCustomException("The following IDs were not found: "+id);
}
startObject.setObjectThatMattersSet(objectThatMattersSet);
}

Accessing a specific element of HasMap of String & ArrayList

I was using an array double xyz[20000][20000] in my project but java is giving "Heap Space" error. I am planning to use Hashmaps instead of the above array. So I need to use Hashmap .
Now the question is that as with java array if an element needs to be accessed we can access it like xyz[10][10], but if I use the above Hashmap then how can i access a specific element like key=10 and the 10th element in the respective array?
HashMap always works that way. You have specified functions in the HashMap class in java to get values of a key, getKey() and getValue() should get you the key and values of the respective key.
Map<int, List<Integer>> entry = new HashMap<int, List<Integer>>();
//rest of the code, putting values etc.
//the accessing data of 10th index
int key = entry.getKey();
List<Integer> values = entry.getValue();
System.out.println("Key = " + key);
System.out.println("Values = " + values.get(10) + "\n");

ArrayList Processing - How to access each index separately

As it is a first time I'm using ArrayList in Processing I'm experiencing some issues.
I have created an Arraylist that stores a PVector (x,y position) of an Ellipsee.
What I'm trying to do is very simple I think but I can't find much info on ArrayLists.
Code:
ArrayList position;
void setup()
{
position= new ArrayList<Vectors>();
}
void draw()
{
position.get(i).display(); //display ellipse
}
void mousePressed()
{
position.add(new Vectors(new PVector(mouseX, mouseY)));
}
So every time mouse is Pressed a new ellipse is created at mouseX mouseY position. What I would like to do is when my I created an amount ellipses, I need to control each one separately to change it's size or color either by clicking on them or with KeyPressed().
This won't compile automatically as I'm assuming your PVector object has already been created and that it has two public attributes of xPosition and yPosition:
// Initialise your arraylist
ArrayList<PVector> listOfPVectors = new ArrayList<PVector>;
// Objects can be added to your list as follows:
PVector pvectorObject = new PVector();
listOfPVectors.add(pvectorObject);
// The size of your ArrayList can be output as follows:
println(listOfPVectors.size());
// You can iterate through every entry in the arraylist as follows:
for(int index = 0; index < listOfPVectors.size(); index ++) {
println("X Position Value = " + listOfPVectors.get(index).xPosition);
println("Y Position Value = " + listOfPVectors.get(index).yPosition);
}
Basically, you use the ArrayList.get(indexPosition) method to retrieve any element you want from your ArrayList. You can then work away with it as normal.
Hope this helps!

static Hashtable<Leader, ArrayList<Integer>> assignedLeader=new Hashtable<Leader, ArrayList<Integer>>(20);

I need to add elements to a hashtable and my hashtable needs to have an array list. But I am not able to find a way to add elements in the table properly. Please help me out.
static Hashtable<Integer, ArrayList<Integer>> assignedLeader =
new Hashtable<Integer, ArrayList<Integer>>(20);
just only for your reference .
static Hashtable<Integer, ArrayList<Integer>> assignedLeader =
new Hashtable<Integer, ArrayList<Integer>>(20);
ArrayList<Integer> al=new ArrayList<Integer>();
al.add(1);
al.add(2);
al.add(3);
assignedLeader.put(1, al);