A lookup object as an argument of a recursion - java

We're using a recursion that iterates through tree nodes and does some computation that is a logical equivalent of something as
public static Result iterate(TreeNode node, Dictionary dictionary ) {
Map<String, Result> accumulated = new HashMap<String, Result>();
for (TreeNode child : node.getChildren()) {
Result partialResult = iterate(child, dictionary);
accumulated.put(child.getId(), partialResult);
}
return completeResult(accumulated);
}
Now the Dicitionary object is not mutated while the recursion is being done. Its simply used as a lookup table. The object is in fact quite big.
Does the fact that we have the dictionary as an argument of our recursive call have a negative impact on the memory/performance? Is this a bad design?

The really interesting issue is: "How is the Dictionary related to the Tree?"
If several Dictionaries need to be used with different iterations, you would indeed pass a Dictionary as a parameter to the iterate method, as you have it right now. (But why it "iterate" static?)
If a Dictionary is a stable property associated with some specific Tree object, its reference should be passed to the constructor and stored as an instance field. The iterate being a method could access it as any other instance field.
Possibly the Dictionary is universal and unique for all Tree objects? Then you might advocate setting the Dictionary as a static class field, and your iterate method would access it as a "global".
Technically, all of the above just passes a reference ("address") around; no copying of a potentially huge object is involved...

I would say your design is correct, in that it should produce correct results. For its performance, you would really need to do some thorough testing to assess, with various combinations of sizes for your tree structure and dictionary. Also, the implementation of Dictionary will probably play a major role in the performance characteristics.
Memory-wise, your current implementation should be the most economical, as you use the existing structures, instead of copying to others, in order to use a faster algorithm.
Passing the dictionary as an argument has the benefit of isolating each recursive run, in the case that the dictionary can change between runs, and provided that you copy the dictionary for each run. Also, it gives you the capability of using the same code to do concurrent searches (using threads) on different trees using different dictionaries. Using a global dictionary wouldn't allow you to do this.

I think this question boils down to whether Java passes by reference or value. Somewhat confusingly Java always passes by value, but where an object is passed the value is the object reference.
So for your example the method iterate takes a parameter Dictionary dictionary. The internals of this object will be stored on the heap. This is an area of memory that is shared among all objects. Additionally your method will have it's own unique reference on the stack. The reference acts as a kind of pointer so your method can lookup the values of dictionary.
When you make the recursive call the JVM will make a new reference to the same dictionary object and put this reference on the stack for the new method call. So now you have two calls to iterate on the call stack, both with their own individual reference to the dictionary object, but only one actual dictionary object on the heap.
If you were to make changes to the dictionary object using either reference it would update the same underlying object so both methods would see these changes.
When the method returns, since the dictionary reference is local to the method it will be removed from the stack. This will reduce the reference count to this object by 1. If the total number of references reaches 0 then your object becomes eligible for garbage collection since nothing will be able to see it.
Back to your question about memory I don't think you need to worry. It's the object on the heap where all of the data will be. References are cheap by comparison (8 bytes for a Java reference). Each reference will in theory take up a little memory but you are only likely to hit problems if your recursive loop doesn't exit.

Related

Efficiently searching a list to find specific Instance, without using `equals()` or `hashCode()`

I'm implementing a simple serialisation mechanism. Serialising an object recursively trawls its fields and writes them out to a stream. To avoid endless loops, when it encounters an object to write it checks to see if it's seen it before, if so then it writes a marker instead. This relies on maintaining a searchable list of objects it's seen before. The list's indexOf() and contains() methods can't use Object.equals, they must use == instead, since an object graph might have two objects in it that are identical in terms of the data, but should not actually be the same object. If i use a simple Map<Object, Integer> with the following example graph, then something bad happens:
root: ParentObject (class Parent)
field1: ChildObject1 (class Child)
data: "Hello"
field2: ChildObject2 (class Child)
data: "Hello"
When serialised the Map finds ChildObject1 when asked to see if ChildObject2 has been written before, because the .equals() method returns true. When deserialised, the object tree now looks like this:
root: ParentObject (class Parent)
field1: ChildObject1 (class Child)
data: "Hello"
field2: <reference to ChildObject1>
Now the problem is that if something modifies ChildObject1 then the apparent ChildObject2 also has that change, which is different behaviour to what would have happened before serialisation. If these objects were immutable then this would not be a problem, but this mechanism is meant to be general purpose and can't ensure immutability, and in the specific case i actually need it for objects are not immutable either.
In a lower level language i would simply create a lookup based on pointer address, but that's not an option here.
I can use a simple List<Object>, and do a linear search on list.get(i) == needle, but this is very inefficient. My first thought is a simple binary search, but what do i search on? There's no identifying information, no key, to use. This seems to preclude the use of any more efficient lookup structure.
I have used Unsafe in the past to output identity information (basically the object's pointer) for debug logging purposes, but this seems, well, "unsafe"! In the back of my mind i have this idea that the JVM might be free to move things around, for example after a GC, which would break this approach, too.
How can i work around this problem?
A linear scan of a list will be O(N) where N is the list length. That's not efficient, and you can't make it efficient.
You could use System.identityHashcode(Object) to calculate a hashcode that will be compatible with ==.
But there is a simpler solution. There is a Map class called IdentityHashMap which is pretty much designed for your use-case. This Map implementation has O(1) lookup and insertion (amortized)

Java object arrays - use of hardware memory cache

Iterating over consecutive elements of an array is generally considered to be more efficient than iterating over consecutive linked list elements because of caching.
This is undoubtedly true as long as elements have elementary data types. But if the elements are objects, my understanding is that only the references to the objects will be stored in the contiguous memory area of the array (which is likely to be cached) while the actual object data will be stored anywhere in main memory and cannot be cached effectively.
As you normally not only iterate over the container but also need to access object data in each iteration, doesn't this more or less kill the performance benefit of the array over the list?
Edit: The comment about different scenarios varying greatly is probably correct. So let's consider a specific one: You search for a specific object in the container. In order to find it you need to compare a given string to another string that is a class variable of the object.
No, for objects ("pointers") there is an indirection in both. A linked list needs for every node to step to the next one. So it still has an overhead.
But yes, in a relative way the gain concerns only a part, very roughly the half of the pure walk through, counting indirection steps.
And ofcourse every indirection makes access more chaotic, slower.
BTW there is the ArrayList too being similar fast as arrays.

Java return array versus pass by reference

I'm designing an API function of a class which will return an array for client to use.But I'm not quite sure whether I should make it a return value or make it as an argument of the function.See below:
Method I:
MyObject[] getMyObject() {... return someObject;}
Method II:
void getMyObject(MyObject[] someObject) {...//assign value to someObject[index]};
In Android API I saw it is very common to return a List<MyObject> or Set<MyObject>. Does it indicate Method I is better? So what are the pros and cons of these two methods in Java?
Update: In method II I mean to assign value to someObject[index], not someObject. My question is not regarding "does Java pass reference or value". It's just simply comparing two feasible way of doing things.
Arrays are not resizeable. So with method 1, you can create a new array with just the right size and return that. With method 2, if the incoming array is the wrong size, you're sunk.
Java does not have pass-by-reference. So assigning something to someObject in method 2 won't do anything for the caller. You can only alter the elements of someObject.
Both ways have advantages and disadvantages.
Version #1
MyObject[] getMyObject() {... return someObject;}
Pros:
This allows you to return an arbitrary number of results.
It is arguably easier for the caller.
Cons:
The called method has to allocate an array. (Alternatively, it has to manage / recycle arrays, which is going to be difficult to do in general. Note that reusing a static array is liable to make the method non-reentrant, etcetera.)
Version #2
void getMyObject(MyObject[] someObject) {...//assign value to someObject[index]};
Pros:
This is potentially better in terms of objects allocated because the caller will be in a better position to recycle / reuse the array.
It allows you to pass values in ... if that is a requirement.
Cons:
The caller has to provide the array, which makes the method more work to use.
The called method has no control over the array size. That means that there is a potential error case if the supplied array is too small ...
There is also a third way, where an array is passed and returned. If the array size is not correct (or maybe if a null is passed) the called method allocates or reallocates an array. The result is either the original array or the reallocated array.
Which is better?
IMO, the first version is better under most circumstances because it is easiest to get right. IMO, you should only consider the alternatives in an API design if there is a demonstrable need to minimize new object allocation. (If you are coding for a Hotspot Java implementation or equivalent, new object allocation is cheap ...)
Finally, a simpler / cleaner way than all of the above is to use a Collection rather than a bare array. Using a standard Collection type allows you to avoid the messiness of preallocating something of the correct size.
Return is more natural to write and read, also pass by "reference" as you call it has more complications than meets the eyes..
someObject[i] = a; //works
someObject = a; // doesnt work
Java has one parameter passing mechanism: everything is passed by value, not by reference.
It's subtle, but true. The implications matter.
You can certainly return any time from that method, be it array, List, or Set. You may or may not be able to alter the contents of the List or Set, because the implementation underneath might have been made unmodifiable by the developer who wrote the method.
Personally, I tend to prefer the collections over arrays. They are more expressive than raw arrays. If I get a Set back, I know that all the entries are unique in some way.

Java: Effeciently keep track of used objects

I have a program that collects objects over time. Those objects are often, but not always duplicates of objects the program has already received. The number of unique objects can sometimes be up in the tens of thousands. As my lists grow, it takes more time to identify whether an object has appeared or not before.
My current method is to store everything in an ArrayList, al; use Collections.sort(al); and use Collections.binarySearch(al, key) to determine whether I've used an object. Everytime I come across a new object I have to insert and sort however.
I'm wondering if there's just a better way to do this. Contains tends to slow up too quickly. I'm looking for something as close to O(1) as possible.
Thanks much.
This is java. For the purpose of understanding what I'm talking about, I basically need a method that does this:
public boolean objectAlreadyUsed(Object o) {
return \\ Have we seen this object already?
}
Instead of using an ArrayList, why wouldn't you use a Set implementation (likely a HashSet)? You'll get constant-time lookup, no sorting needed.
N.B. your objects will need to correctly override hashCode() and equals().
This begs the question - why not use a data structure that doesn't allow duplicates (e.g. Set)? If you attempt to add a duplicate item, the method will return false and the data structure will remain unchanged.
Make sure the objects have correct equals() and hashCode() methods, and store them in a HashSet. Lookup then becomes constant time.
If retaining unwanted objects becomes an issue, by the way, you could consider using one of the many WeakHashSet implementations available on the Internet -- it will hold the objects but still allow them to be garbage collected if necessary.

Java sets: why there is no T get(Object o)? [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I understand that only one instance of any object according to .equals() is allowed in a Set and that you shouldn't "need to" get an object from the Set if you already have an equivalent object, but I would still like to have a .get() method that returns the actual instance of the object in the Set (or null) given an equivalent object as a parameter.
Any ideas/theories as to why it was designed like this?
I usually have to hack around this by using a Map and making the key and the value same, or something like that.
EDIT: I don't think people understand my question so far. I want the exact object instance that is already in the set, not a possibly different object instance where .equals() returns true.
As to why I would want this behavior, typically .equals() does not take into account all the properties of the object. I want to provide some dummy lookup object and get back the actual object instance in the Set.
While the purity argument does make the method get(Object) suspect, the underlying intent is not moot.
There are various class and interface families that slightly redefine equals(Object). One need look no further than the collections interfaces. For example, an ArrayList and a LinkedList can be equal; their respective contents merely need to be the same and in the same order.
Consequently, there are very good reasons for finding the matching element in a set. Perhaps a clearer way of indicating intent is to have a method like
public interface Collection<E> extends ... {
...
public E findMatch(Object o) throws UnsupportedOperationException;
...
}
Note that this API has value broader that within Set.
As to the question itself, I don't have any theory as to why such an operation was omitted. I will say that the minimal spanning set argument does not hold, because many operations defined in the collections APIs are motivated by convenience and efficiency.
The problem is: Set is not for "getting" objects, is for adding and test for presence.
I understand what are you looking for, I had a similar situation and ended using a map of the same object in key and value.
EDIT: Just to clarify: http://en.wikipedia.org/wiki/Set_(abstract_data_type)
I had the same question in java forum years ago. They told me that the Set interface is defined. It cannot be changed because it will break the current implementations of Set interface. Then, they started to claim bullshit, like you see here: "Set does not need the get method" and started to drill me that Map must always be used to get elements from a set.
If you use the set only for mathematical operations, like intersection or union, then may be contains() is sufficient. However, Set is defined in collections to store data. I explained for need get() in Set using the relational data model.
In what follows, an SQL table is like a class. The columns define attributes (known as fields in Java) and records represent instances of the class. So that an object is a vector of fields. Some of the fields are primary keys. They define uniqueness of the object. This is what you do for contains() in Java:
class Element {
public int hashCode() {return sumOfKeyFields()}
public boolean equals(Object e) {keyField1.equals(e) && keyField2.equals(e) && ..}
I'm not aware of DB internals. But, you specify key fields only once, when define a table. You just annotate key fields with #primary. You do not specify the keys second time, when add a record to the table. You do not separate keys from data, as you do in mapping. SQL tables are sets. They are not maps. Yet, they provide get() in addition to maintaining uniqueness and contains() check.
In "Art of Computer Programming", introducing the search, D. Knuth says the same:
Most of this chapter is devoted to the study of a very simple search
problem: how to find the data that has been stored with a given
identification.
You see, data is store with identification. Not identification pointing to data but data with identification. He continues:
For example, in a numerical application we might want
to find f(x), given x and a table of the values of f; in a
nonnumerical application, we might want to find the English
translation of a given Russian word.
It looks like he starts to speak about mapping. However,
In general, we shall suppose that a set of N records has been stored,
and the problem is to locate the appropriate one. We generally require
the N keys to be distinct, so that each key uniquely identifies its
record. The collection of all records is called a table or file,
where the word "table" is usually used to indicate a small file, and
"file" is usually used to indicate a large table. A large file or a
group of files is frequently called a database.
Algorithms for searching are presented with a so-called argument, K,
and the problem is to find which record has K as its key. Although the
goal of searching is to find the information stored in the record
associated with K, the algorithms in this chapter generally ignore
everything but the keys themselves. In practice we can find the
associated data once we have located K; for example, if K appears in
location TABLE + i, the associated data (or a pointer to it) might be
in location TABLE + i + 1
That is, the search locates the key filed of the record and it should not "map" the key to the data. Both are located in the same record, as fileds of java object. That is, search algorithm examines the key fields of the record, as it does in the set, rather than some remote key, as it does in the map.
We are given N items to be sorted; we shall call them records, and
the entire collection of N records will be called a file. Each
record Rj has a key Kj, which governs the sorting process. Additional
data, besides the key, is usually also present; this extra "satellite
information" has no effect on sorting except that it must be carried
along as part of each record.
Neither, I see no need to duplicate the keys in an extra "key set" in his discussion of sorting.
... ["The Art of Computer Programming", Chapter 6, Introduction]
entity set is collection or set all entities of a particular entity type
[http://wiki.answers.com/Q/What_is_entity_and_entity_set_in_dbms]
The objects of single class share their class attributes. Similarly, do records in DB. They share column attributes.
A special case of a collection is a class extent, which is the
collection of all objects belonging to the class. Class extents allow
classes to be treated like relations
... ["Database System Concepts", 6th Edition]
Basically, class describes the attributes common to all its instances. A table in relational DB does the same. "The easiest mapping you will ever have is a property mapping of a single attribute to a single column." This is the case I'm talking about.
I'm so verbose on proving the analogy (isomorphism) between objects and DB records because there are stupid people who do not accept it (to prove that their Set must not have the get method)
You see in replays how people, who do not understand this, say that Set with get would be redundant? It is because their abused map, which they impose to use in place of set, introduces the redundancy. Their call to put(obj.getKey(), obj) stores two keys: the original key as part of the object and a copy of it in the key set of the map. The duplication is the redundancy. It also involves more bloat in the code and wastes memory consumed at Runtime. I do not know about DB internals, but principles of good design and database normalization say that such duplication is bad idea - there must be only one source of truth. Redundancy means that inconsistency may happen: the key maps to an object that has a different key. Inconsistency is a manifestation of redundancy. Edgar F. Codd proposed DB normalization just to get rid of redundancies and their inferred inconsistencies. The teachers are explicit on the normalization: Normalization will never generate two tables with a one-to-one relationship between them. There is no theoretical reason to separate a single entity like this with some fields in a single record of one table and others in a single record of another table
So, we have 4 arguments, why using a map for implementing get in set is bad:
the map is unnecessary when we have a set of unique objects
map introduces redundancy in Runtime storage
map introduces code bloat in the DB (in the Collections)
using map contradicts the data storage normalization
Even if you are not aware of the record set idea and data normalization, playing with collections, you may discover this data structure and algorithm yourself, as we, org.eclipse.KeyedHashSet and C++ STL designers did.
I was banned from Sun forum for pointing out these ideas. The bigotry is the only argument against the reason and this world is dominated by bigots. They do not want to see concepts and how things can be different/improved. They see only actual world and cannot imagine that design of Java Collections may have deficiencies and could be improved. It is dangerous to remind rationale things to such people. They teach you their blindness and punish if you do not obey.
Added Dec 2013: SICP also says that DB is a set with keyed records rather than a map:
A typical data-management system spends a large amount of time
accessing or modifying the data in the records and therefore requires
an efficient method for accessing records. This is done by identifying
a part of each record to serve as an identifying key. Now we represent
the data base as a set of records.
Well, if you've already "got" the thing from the set, you don't need to get() it, do you? ;-)
Your approach of using a Map is The Right Thing, I think. It sounds like you're trying to "canonicalize" objects via their equals() method, which I've always accomplished using a Map as you suggest.
I'm not sure if you're looking for an explanation of why Sets behave this way, or for a simple solution to the problem it poses. Other answers dealt with the former, so here's a suggestion for the latter.
You can iterate over the Set's elements and test each one of them for equality using the equals() method. It's easy to implement and hardly error-prone. Obviously if you're not sure if the element is in the set or not, check with the contains() method beforehand.
This isn't efficient compared to, for example, HashSet's contains() method, which does "find" the stored element, but won't return it. If your sets may contain many elements it might even be a reason to use a "heavier" workaround like the map implementation you mentioned. However, if it's that important for you (and I do see the benefit of having this ability), it's probably worth it.
So I understand that you may have two equal objects but they are not the same instance.
Such as
Integer a = new Integer(3);
Integer b = new Integer(3);
In which case a.equals(b) because they refer to the same intrinsic value but a != b because they are two different objects.
There are other implementations of Set, such as IdentitySet, which do a different comparison between items.
However, I think that you are trying to apply a different philosophy to Java. If your objects are equal (a.equals(b)) although a and b have a different state or meaning, there is something wrong here. You may want to split that class into two or more semantic classes which implement a common interface - or maybe reconsider .equals and .hashCode.
If you have Joshua Bloch's Effective Java, have a look at the chapters called "Obey the general contract when overriding equals" and "Minimize mutability".
Just use the Map solution... a TreeSet and a HashSet also do it since they are backed up by a TreeMap and a HashMap, so there is no penalty in doing so (actualy it should be a minimal gain).
You may also extend your favorite Set to add the get() method.
[]]
I think your only solution, given some Set implementation, is to iterate over its elements to find one that is equals() -- then you have the actual object in the Set that matched.
K target = ...;
Set<K> set = ...;
for (K element : set) {
if (target.equals(element)) {
return element;
}
}
If you think about it as a mathematical set, you can derive a way to find the object.
Intersect the set with a collection of object containing only the object you want to find. If the intersection is not empty, the only item left in the set is the one you were looking for.
public <T> T findInSet(T findMe, Set<T> inHere){
inHere.retainAll(Arrays.asList(findMe));
if(!inHere.isEmpty){
return inHere.iterator().next();
}
return null;
}
Its not the most efficient use of memory, but its functionally and mathematically correct.
"I want the exact object instance that is already in the set, not a possibly different object instance where .equals() returns true."
This doesn't make sense. Say you do:
Set<Foo> s = new Set<Foo>();
s.Add(new Foo(...));
...
Foo newFoo = ...;
You now do:
s.contains(newFoo)
If you want that to only be true if an object in the set is == newFoo, implement Foo's equals and hashCode with object identity. Or, if you're trying to map multiple equal objects to a canonical original, then a Map may be the right choice.
I think the expectation is that equals truely represent some equality, not simply that the two objects have the same primary key, for example. And if equals represented two really equal objects, then a get would be redundant. The use case you want suggests a Map, and perhaps a different value for the key, something that represents a primary key, rather than the whole object, and then properly implement equals and hashcode accordingly.
Functional Java has an implementation of a persistent Set (backed by a red/black tree) that incidentally includes a split method that seems to do kind of what you want. It returns a triplet of:
The set of all elements that appear before the found object.
An object of type Option that is either empty or contains the found object if it exists in the set.
The set of all elements that appear after the found object.
You would do something like this:
MyElementType found = hayStack.split(needle)._2().orSome(hay);
Object fromSet = set.tailSet(obj).first();
if (! obj.equals(fromSet)) fromSet = null;
does what you are looking for. I don't know why java hides it.
Say, I have a User POJO with ID and name.
ID keeps the contract between equals and hashcode.
name is not part of object equality.
I want to update the name of the user based on the input from somewhere say, UI.
As java set doesn't provide get method, I need to iterate over the set in my code and update the name when I find the equal object (i.e. when ID matches).
If you had get method, this code could have been shortened.
Java now comes with all kind of stupid things like javadb and enhanced for loop, I don't understand why in this particular case they are being purist.
I had the same problem. I fixed it by converting my set to a Map, and then getting them from the map. I used this method:
public Map<MyObject, MyObject> convertSetToMap(Set<MyObject> set)
{
Map<MyObject, MyObject> myObjectMap = new HashMap<MyObject, MyObject>();
for(MyObject myObject: set){
myObjectMap.put(myObject, myObject);
}
return myObjectMap
}
Now you can get items from your set by calling this method like this:
convertSetToMap(myset).get(myobject);
You can override the equals in your class to let it check on only a certain properties like Id or name.
if you have made a request for this in Java bug parade list it here and we can vote it up. I think at least the convenience class java.util.Collections that just takes a set and an object
and is implemented something like
searchSet(Set ss, Object searchFor){
Iterator it = ss.iterator();
while(it.hasNext()){
Object s = it.next();
if(s != null && s.equals(searchFor)){
return s;
}
}
This is obviously a shortcoming of the Set API.
Simply, I want to lookup an object in my Set and update its property.
And I HAVE TO loop through my (Hash)Set to get to my object... Sigh...
I agree that I'd like to see Set implementations provide a get() method.
As one option, in the case where your Objects implement (or can implement) java.lang.Comparable, you can use a TreeSet. Then the get() type function can be obtained by calling ceiling() or floor(), followed by a check for the result being non-null and equal to the comparison Object, such as:
TreeSet myTreeSet<MyObject> = new TreeSet();
:
:
// Equivalent of a get() and a null-check, except for the incorrect value sitting in
// returnedMyObject in the not-equal case.
MyObject returnedMyObject = myTreeSet.ceiling(comparisonMyObject);
if ((null != returnedMyObject) && returnedMyObject.equals(comparisonMyObject)) {
:
:
}
The reason why there is no get is simple:
If you need to get the object X from the set is because you need something from X and you dont have the object.
If you do not have the object then you need some means (key) to locate it. ..its name, a number what ever. Thats what maps are for right.
map.get( "key" ) -> X!
Sets do not have keys, you need yo traverse them to get the objects.
So, why not add a handy get( X ) -> X
That makes no sense right, because you have X already, purist will say.
But now look at it as non purist, and see if you really want this:
Say I make object Y, wich matches the equals of X, so that set.get(Y)->X. Volia, then I can access the data of X that I didn have. Say for example X has a method called get flag() and I want the result of that.
Now look at this code.
Y
X = map.get( Y );
So Y.equals( x ) true!
but..
Y.flag() == X.flag() = false. ( Were not they equals ?)
So, you see, if set allowed you to get the objects like that It surely is to break the basic semantic of the equals. Later you are going to live with little clones of X all claming that they are the same when they are not.
You need a map, to store stuff and use a key to retrieve it.
I understand that only one instance of any object according to .equals() is allowed in a Set and that you shouldn't "need to" get an object from the Set if you already have an equivalent object, but I would still like to have a .get() method that returns the actual instance of the object in the Set (or null) given an equivalent object as a parameter.
The simple interface/API gives more freedom during implementation. For example if Set interface would be reduced just to single contains() method we get a set definition typical for functional programming - it is just a predicate, no objects are actually stored. It is also true for java.util.EnumSet - it contains only a bitmap for each possible value.
It's just an opinion. I believe we need to understand that we have several java class without fields/properties, i.e. only methods. In that case equals cannot be measured by comparing function, one such example is requestHandlers. See the below example of a JAX-RS application. In this context SET makes more sense then any data structure.
#ApplicationPath("/")
public class GlobalEventCollectorApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(EventReceiverService.class);
classes.add(VirtualNetworkEventSerializer.class);
return classes;
}
}
To answer your question, if you have an shallow-employee object ( i.e. only EMPID, which is used in equals method to determine uniqueness ) , and if you want to get a deep-object by doing a lookup in set, SET is not the data-structure , as its purpose is different.
List is ordered data structure. So it follows the insertion order. Hence the data you put will be available at exact position the time you inserted.
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.get(0); // will return value 1
Remember this as simple array.
Set is un ordered data structure. So it follows no order. The data you insert at certain position will be available any position.
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
//assume it has get method
set.get(0); // what are you expecting this to return. 1?..
But it will return something else. Hence it does not make any sense to create get method in Set.
**Note****For explanation I used int type, this same is applicable for Object type also.
I think you've answered your own question: it is redundant.
Set provides Set#contains (Object o) which provides the equivalent identity test of your desired Set#get(Object o) and returns a boolean, as would be expected.

Categories

Resources