I have a very simple question that I would like to ask. There are 2 ways by which you initialize a variable :
1.
List<SalesReturnJson> salesReturnJsons=new LinkedList<>();
salesReturnJsons=salesRepository.findSales();
2.
List<SalesReturnJson> salesReturnJsons=salesRepository.findSales();
So in this 2 scenerios how is the memory allocated and In the second scenerio which implementation(LinkedList or ArrayList) of List is called.
Any help will be highly appreciated.
If in the first scenario the second line is exactly below the first line, the "new" statement would have no effect. You create an empty LinkedList, put a reference on it, then you change the reference to point to another List (I suppose findSales returns a List) and finally the garbage collector of java will erase the empty LinkedList, since there is no reference to it anymore.
In the second scenario you return a List (as I suppose) and put a reference to this List.
In both cases an object returned by salesRepository.findSales() will be assigned to your variable. Since the implementation is the same in both cases, without knowing the actual implementation we can only say that the object will be of the same class in both cases, however, creating an object and then re-assigning the variable to another reference as in your first example makes little sense. The second will achieve the same result, but with reduced effort.
Both scenarios end up with exactly the same List in your salesReturnJsons variable, with the List type being the one returned by salesRepository.findSales(). From the code given, we can't tell what type is actually returned from this method.
The only difference is, the first scenario creates an absolutely unnecessary empty LinkedList, stores it into your salesReturnJsons variable, and immediately replaces it by the list from salesRepository.findSales(), making the LinkedList garbage. So, please use the second version.
If (for whatever special reason) your intent might be to have a LinkedList of the salesRepository.findSales() results, then you could do:
List<SalesReturnJson> salesReturnJsons=
new LinkedList<SalesReturnJson>(salesRepository.findSales());
That will copy the elements from the method result into a fresh LinkedList, then you are sure about the List type.
But the typical code snippet would be your version 2.
Related
I'm writing a soft that process some annotations. One of annotation's parameters is an array. One object finds this array and pass it to another object to process it. And then findbugs starts to scream that I'm passing a private array that may be mutated by malicious code. so the question is: is that true? can annotation parameters be changed in runtime?
This is true: you pass a reference to an array, and arrays are mutable. The callee can modify this array.
Your best course of action is to pass a copy of that array to the callee instead of the original array, for instance by using Arrays.copyOf().
Alternatively, instead of an array, you may want to return a List instead and use the Collections.unmodifiableList() wrapper since this will avoid unnecessary copies.
Arrays returned through reflection should be a fresh copy every time they are retrieved, so there's no problem.
From a mobile code, or in general code quality, perspective you should expect an array returned or passed as an argument to an untrusted method to be malicious modified. Similarly on the receiver side of things, arrays passed as parameters or returned from callbacks may be malicious modified later. So there arrays need to be copied before handing them out and also as they are received (even before any validation).
#fge mention Lists. When sending these out, an unmodifiable collection cannot be modified by the receiver. Receiving collections is a little more tricky. Obviously taking an untrusted List and wrapping it with unmodifiableList wont work. new ArrayList<>(things) is the way to go. Don't attempt to clone a malicious ArrayList because you cannot be sure what clone actually does.
Obviously, if you have an array of mutable objects, both the array and elements will need to be copied.
Given an IP Address Range ( a.b.c.d - a.b.c.e) i would like a method to return the ip address's in an array list between the range.
Option 1 :
public static int getIPAddressesFromRange(String rangeStr, List list ) ;
return value is count and the input list would be populated with list of IP's the range has
Option 2:
public static List getIPAddressesFromRange(String rangeStr)
return value is the list of ip addresses'
My Option is 2, but that is intuition, not able to support my argument though.
Edit: Is there any design principle the option 1 is violation ?
I'd say
public static List<String> getIPAddressesFromRange(String rangeStr)
if you decide to represent IP addresses as strings.
Arguments against #1:
The caller needs to construct the list in advance
It is not straightforward what the return value is unless you document it
The method mutates one of its arguments, which is not in general forbidden, but it is best to avoid surprising the user of your API (especially if they are prone not to read the documentation)
Passing in a null value accidentally for the list parameter will result in a NullPointerException.
You can always get the length of the list from the list itself if you really care about it.
Prefer the option 2 to the option 1.
The list contains its count anyway, so there is no need to return two values (the count and the list).
Also, since you know the type of the list, you can use generics: List<String>.
Finally, you might also consider taking two arguments: the beginning and the end of the range.
Why do you want to return count in first method? You can fetch the number of IP's from List itself.
Second method should be the preferred one
Your second option is best because the first option has two problems:
It's redundant. If a List is returned, you can use its size() method to get that count, so you gain nothing by returning the count.
The list must be validated and in some cases the method outright cannot perform its work. If the caller passes null, there is danger of a NullPointerException being thrown if the code was not written carefully. Also in that case, reassigning the parameter to point to a new list will not be observed by the caller, so your only remotely sane option is to throw a clear exception. With the second option, you have full control of the list until it is returned to the caller.
Option two is probably better, since it is clear for any reader what is the method returning.
Method 1 might cause future coders to spend time thinking what is this parameter (unless it is properly documented), while method 2 is realy straight forward.
Option two also makes it more neat if you later need to iterate on the retrieved list, no need for temporary variables:
for (Object o : getIPAddressesFromRange(String rangeStr)) { ... }
You should also prefer using the generic type List<> and not the raw type.
Stuff in, stuff out. That's what your Option 2 does.
Option 1 mutates its input argument and returns redundant value (count, which can be got from the list).
Another thing is, perhaps a range of IP addresses would be described better by some other type than a String.
IMO method signature suggests it will return a list of ip addresses from range, not how many addresses are in this range, hence I'm also for option 2.
I think the 2nd one is better :
The count is the size of the list
You don't have to give a list to the function
Less null pointer exception risk
Your intuition is mine also, it is better to let getIPAddressesFromRange use its preferred implementation of List and avoid someone to give you an already populated list.
My opinion is that the second method signature is generally the best one as the first one will exposes your list object to concurrent modification. Thus, at the end of your method, it may hold less, more, other objects than expected.
It depends on whether you want to fill pre-created lists, or create new ones.
For example: You could do multiple calls to your function using the same List object to save some memory.
Or: To compare multiple lists, you may want to return a new List for each call.
I would go with Option 2.
I guess this question that would have already been asked here. I searched but could not find anything similar. So here goes --
I have a custom data object Method and Method is as follows --
public Class Method {
List<String> inputParameters;
String resultVariableName;
}
Now i have a LinkedList<Method> which acts as a repository of Method objects.
Given a Method object is there a way in which the correct index of the Method object can be concretely determined.
My question arises from the face that LinkedList class has an indexOf routine but this routine returns the first occurrence of the object but then there is no given that 2 copies of Method object can not reside in the LinkedList(right ?)
Would tagging every Method object as I add it to the LinkedList solve my purpose and if so is there an ideal way to do it ?
EDIT :
Explaining my use case a little further.
My code basically reads a Velocity template top-down and creates Method objects. One Method object is created for every velocity routine encountered.
This explains why the same element can be stored at multiple indices in the LinkedList as there is no real restriction on how many number of time a Velocity routine is called or the inputs/results provided to the Velocity routine.
Now, i have a UI component, one JButton per Method object reference in the LinkedList<Method> by using which the user can click and edit the Method object.
Thus i need to know which exact Method object reference to edit in the event that same elements reside twice or more number of times in the LinkedList<Method>
What do you mean by the "correct" index in the first place? If the linked list can contain the same element twice or more (and be careful here - the list will only contain a reference to a Method object, not the object itself) then which index would be "correct" in your view?
Of course you can just iterate over the linked list yourself and return all indexes at which a given Method reference occurs, but it's not clear what you're trying to do with it.
Note that indexes aren't often used with linked lists to start with, as obtaining the element at a given index is an O(n) operation.
Duplicates are allowed in LinkedList's.
LinkedList does not avoid duplicates, it may have more than one copy.
You can put a logic to avoid multiple instances, extend the linkedlist class and override the add function to check if Method object already exists.
OR
If you want to get all instances of the Method object, you can use a ListIterator and collect all instances of it, and return this collection as a result.
"there is not given 2 copies of Method object can not reside in the LinkedList", if this is a scenario, how will you identify which object to retrieve??
In this case, I would suggest you to use a LinkedHashMap, where you can use a Identifier as a key to uniquely identify a Method's object.
If fooService.getFoos() returns List<Foo>.
then you can write this:
List<Foo> fooList = fooService.getFoos();
or this:
List<Foo> fooList = new ArrayList(fooService.getFoos());
Is there any significant difference in the resulting fooList between these two approaches?
Yes - you are creating a completely new List, containing the elements of the original one. You are duplicating the collection in memory, and iterating it from start to end. You are also not using instance provided by the service, and you can't modify the original. And finally, you've omitted the generics declaration in the 2nd snippet.
So use the first option.
Update: you indicated you are not allowed to modify the original list. This is actually a problem of fooService, not of its clients. If the service is also in your control, return Collections.unmodifiableList(originalList) - thus clients won't be able to perform modification operations (on attempt an exception will be thrown)
The second isn't really a good idea because you omit the generic part.
But the main problem is the unnecessary code which will be called. You can look at the ArrayList code source, and you'll see all the operations used in the constructor. If you only need a List, and fooService.getFoos() returns a valid List, you should stick with it.
The result of those two statement will be more or less the same unless:
later you check if your list is an instance of ArrayList and cast it, but let's face it, you would have declared ArrayList<Foo> if it was the case.
the list returned by fooService.getFoos() shouldn't be modified (for any reason) but you still want modify elements in the List on your side (without affecting the original list).
Resources :
grepcode - ArrayList
I'd stick with the first one just because it reads lots easier and makes much more sense than the second one.
In the second statement it returns only of List type. If you are sure of method returning of same type den you can use firs type.
I understand that in order to copy an arraylist and have two lists independent of one another you must use a deep copy (copying the objects from one list to another not just the references), however is there a way this can be done cross-class?
For example; I am calling Class2 from Class1. In Class2 objects are added to an ArrayList of custom objects upon an event. I would like to be able to transfer this ArrayList to Class1 but whenever I try I get a NullPointer.
Any clues??
This is highly indicative of a design flaw.
See if you can't accomplish the same goal by wrapping your list in a class, sharing the class and using it to control access to the list.
The only case where this wouldn't just outright work is if your two classes must modify the list independently.
If this is a requirement, then I would probably hand a different instance of the wrapper class to each modifying class (with a reference to the same source list), then have a way for newly added data to be tagged with an ID referring to the original class--that way when you query, the wrapper would only return untagged items (items that were part of the original shared list) and items tagged with it's own ID.
Either that or the wrapper class could contain a second list and when queried, return the combined results of the original and second lists.
I've almost never wanted a deep copy. It happens, but it's quite rare.
If you post more info, maybe we can be more specific in helping with the redesign.
ALSO: (Edit)
Chances are that the copied array list isn't your problem--it's probably that it wasn't TRULY a deep copy. For a deep copy, it means you implement a copy method (I believe they are supposed to be called .clone(), I never use this stuff--as I said, it's bad juju) for each object in the array list, then you call your copy method on each one to get the new copy in your next list.
Furthermore, any objects referenced by your copied object should probably be cloned as well. "Deep" means all the way down the tree.
I'm guessing you're failing somewhere in the process.
I'd really like to hear why you feel you need a copy instead of a reference.
My suggestion is for you to create a getArray() method and call it from the other class. This method should create a copy of the ArrayList because you should not "transfer" variables within classes; always with get() method so OO paradigm stays intact.
Do something like this:
Class 1
public ArrayList<Object> getArray() {
ArrayList<Object> aux = new ArrayList<Object>();
for(Object x : list) //object is the string, int, etc...
aux.add(x.clone()) //assuming the Object has a clone method!
return aux;
}
On Class 2, just call this method. Then just look at the test from the other answer about the null exception, should work.
Hope it helps.