Allowing Only Specific Class Objects in ArrayList - java

I Know I can use Generics while defining the ArrayList to do that. But here the case is different.
I have a ArrayList, which when defined accepts any type of Objects. Once the user inserts the first Object, I need to use Class Reference to Find the Class of that Object and then have to ensure that only Objects of that Class are inserted in the ArrayList.
Example:
ArrayList arrayList = new ArrayList();
Now lets say the User enters an object b, of Class B in the arrayList, then from now onwards, I must only allow objects of type B to be added to the arrayList.
I know that I can find the class of the Object inserted using:
arrayList.get(0).getClass();
But what after it? How will I use the Class type I just found?

Since this is an interview question I won't give you a complete answer, but you might want to take a look at the Class.isAssignableFrom method.

You cannot use generics for this, you need to implement runtime checks.
One way would be to subclass ArrayList and implement the various add methods in a way that checks the type of what is being added.
get(0).getClass().cast(newObject);
// will throw a ClassCastException if it does not match

hmm .. you can do the comparison on the class names - not elegant but should do your work ..
get(0).getClass().getName().equals(classname for the pushed value)

I see some design issues in the code rather how to solve this issue. The flow of the code should determine what the code is doing so that it does not send the collection to a method which can put any arbitrary objects (by checking or not) in it.
I would advise to revisit the design.
For example, if someone is trying to put a soccer ball into the collection and then the collection should be passed into a method where it can deal with a soccer ball. They can use a common code or command pattern for handling any ball or specific behavior for soccer ball and so on.
The same is true if the code wants to put a base ball into a collection, it better knows what its going to do next.
It is a design issue... It is not a code issue.

Related

Why to keep interface as reference? [duplicate]

This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 9 years ago.
I have observed in Java programming language, we code like following:
List mylist = new ArrayList();
Why we should not use following instead of above one?
ArrayList mylist = new ArrayList();
While the second option is viable, the first is preferable in most cases. Typically you want to code to interfaces to make your code less coupled and more cohesive. This is a type of data abstraction, where the user of mylist (I would suggest myList), does not care of the actual implementation of it, only that it is a list.
We may want to change the underlying data structure at some point, and by keeping references, we only need to change the declaration.
The separation of Abstract Data Type and specific implementation is one the key aspects of object oriented programming.
See Interface Instansiation
Just to avoid tight coupling. You should in theory never tie yourself to implementation details, because they might change, opposite to interface contract, which is supposed to be stable. Also, it really simplifies testing.
You could view interface as an overall contract all implementing classes must obey. Instead, implementation-specific details may vary, like how data is represented internally, accessed, etc. - the information that you'd never want to rely on.
If you use ArrayList, you are saying it has to be an ArrayList, not any other kind of List, and to replace it you would have to change every reference to the type. If you use List you are making it clear there is nothing special about the List and it is used as a plain list. It can be changed to another List by changing just one line.

Returning two different values from method

I have method that parses a list of String records into objects and returns List of objects. So my method signature is like this.
public List<ParsedObject> parse(String[] records);
But I also want to return, other metrics like number of string records that were not parsed successfully. Now I get confused, how to return this metric. One option would be to create another wrapper class that holds both list of parsed records and members to store these metrics.
But I face this situation very often and this way I would end up in creating many wrapper classes.
Not sure if I explained well. Any suggestions here?
Java does not support returning multiple values from a function, unfortunately. You can create a wrapper class, like you said. Another option is to pass in an array of integers or a "metrics" object or something like that and modify it inside Parse. Slightly better might be to have one or more instance variables (rather than method variables) to keep track of any sort of diagnostic information you need.
Your question has already been discussed (see this for example: Should Java method arguments be used to return multiple values? ). I personally think that you should either make two method calls, if the returned data is not related. If they are, then you should create a "wrapper" class as you call it. If they really are related data then they probably belong in the same class anyway.
I don't personally favor modifying passed in objects because to me it is a side effect, and it is not clear to see what the method really does.
Another way to think of it is to use the factory pattern (see http://en.wikipedia.org/wiki/Factory_method_pattern) if the object you are building is complex.
Create a ParseResult object. You could include the List, number of records parsed, errors, etc. Make it generic enough so that it could be returned from different methods. You could even make it a base class and return classes that extend from it. Just keeping thinking in terms of objects.
You can return a complex object containing the list and all the information you need.
Maybe this could help http://www.yoda.arachsys.com/java/parameters.html
I was going to suggest to you some kind of 'c++ pair' type, but then I found this: What is the equivalent of the C++ Pair<L,R> in Java?
A wrapper class is the standard way of returning more information from a function. Another alternative would be to pass another parameter by reference and modify it in your function, thus effectively returning new information to the caller. For example, in your case you would pass an empty list and add all the parsed elements in that list. The return type could be a metric or an error code. Thus the caller will have both pieces of information.
This is a very common problem for many people who develop using Java. In other languages, such as Scala, one can create tuples, which are anonymous objects which can hold multiple values, and use them as arguments or return values.

List versus ArrayList as reference type?

Ok so I know that Set, List and Map are interfaces but what makes the first line of code any better than the second line?
List myArr = new ArrayList();
ArrayList myArr = new ArrayList();
If you use the first form, you are saying all you are ever going to use is the functionality of the List interface - nothing else, especially nothing extra added by any implementation of it. This means you can easily change the implementation used (e.g. just substitute LinkedList for ArrayList in the instantiation), and not worry about it breaking the rest of the code because you might have used something specific to ArrayList.
A useful general principle about types in programming (sometime referred to as the robustness principle) is as follows:
Be liberal about what you accept
Be conservative about what you emit
List is more liberal than ArrayList, since List can be any kind of List implementation e.g. an ArrayList, a LinkedList or FrancosSpecialList. Hence it is a good idea to be liberal and accept any kind of list since you may want to change the implementation later.
The main reason to use ArrayList explicitly as a type (your second case) is if you need to use methods that are specific to ArrayList that are not available through the List interface. In this case a generic List won't work (unless you want to do lots of ugly and confusing casting), so you might as well be explicit and use an ArrayList directly. This has the added bonus of hinting to a reader that specific features of ArrayList are needed.
As you can see from the source of ArrayList here, most of the methods implemented are annotated as #override because all of them that are defined through List interface so, if you are gonna use just basic functionalities (that is what you are gonna do most of the time) the difference won't be any practical one.
The difference will come if someday you will think that the features of the ArrayList are not suitable anymore for your kind of problem and you will need something different (a LinkedList for example). If you declared everything as List but instantiated as ArrayList you will easily switch to new implementation by changing the instantiations to new LinkedList() while in other case you will have to change also all variable declarations.
Using List list = new ArrayList() is more OOP style since you declare that you don't care about the specific implementation of the list, and that you want to discard the static information about the type since you will rely on the interface provided by this kind of collection abstracting from its implementation.

What is the Collections.checkedList() call for in java?

I just want to know for what java.util.Collections.checkedList() is actually used.
I have some code that I know is returning me a List<String> but it's being passed through a chain of messaging calls and returned to me as a java.io.Serializable. Is that checkedList call good for me to turn my Serializable into a List<String>? I know I can cast it to a java.util.List, but I'd rather not have to check each element and I'm not comfortable with assuming each element is a String.
It is used in part as a debugging tool to find where code inserts a class of the wrong type, in case you see that happening, but can't figure out where.
You could use it as part of a public API that provides a collection and you want to ensure the collection doesn't get anything in it of the wrong type (if for example the client erases the generics).
The way you could use it in your case is:
Collections.checkedList(
new ArrayList<String>(uncertainList.size()), String.class)
.addAll(uncertainList);
If that doesn't throw an exception, then you know you are good. That isn't exactly a performance optimized piece of code, but if the list contents are reasonably small, it should be fine.
Not quite:
Collections.checkedList will only decorate the list to prevent any future inserts with objects of the wrong class, it won't check all the elements that are already in the list.
However, you could make a new checkedList, and then call addAll and pass in the list you are unsure about - rather than writing the loop yourself.
A discussion of what checkedList could be used for is available in the documentation for checkedCollection. The reasons given are:
as a debugging aid (if someone has used an unchecked cast)
to ensure safety when passing a collection to be populated by third-party code.
You could use the following from google collections to check that the list does only contain strings:
Iterables.all(list, Predicates.instanceOf(String.class))

Which is the better way to setListData in a jList, vector or array?

In this answer to a question I asked. Kathy Van Stone says that adding an array like so
jList1.setListData(LinkedHashMap.keySet().toArray());
is a better way than to do it like this
jList1.setListData(new Vector<String>(LinkedHashMap.keySet()));
I am wondering if there was any truth to this and if so what the reason behind it was.
Do you need the synchronization afforded by the Vector class? If not, then you don't want to use the Vector class. (If only JList allowed using an ArrayList in its place.) The cost of uncontended synchronization is way lower in recent JVM versions, way lower than it used to be. Still, there's no reason to use unnecessary synchronization.
It looks like Kathy Van Stone may be referring to that extra synchronization in Vector.
Note carefully the JavaDoc for public JList(Vector<?> listData):
The created model references the given Vector directly. Attempts to modify the
Vector after constructing the list results in undefined behavior.
Unfortunately, the JavaDoc for public JList(Object[] listData) has the same warning:
The created model references the given array directly. Attempts to modify the
array after constructing the list results in undefined behavior.
You have to decide if there is any likelihood that someone decides that the Vector is useful later in the same method and thus modifies the code like this:
Vector vec = new Vector<String>(LinkedHashMap.keySet());
jList1.setListData(vec);
// Other stuff with Vector
vec.add( .... ); // Adding some data type that fits in the Vector
... or of course the same change with the Array constructor version.
Take a look at implementation of both setListData methods in JList class and you will see that it really doesn't matter.
I would prefer the first one, simply because there is no need to involve yet another collection (Vector)

Categories

Resources