What is the Collections.checkedList() call for in java? - 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))

Related

What is the use of singletonList?

I was looking around for some elegant solution to removing null values from a List. I came across the following post, which says I can use list.removeAll(Collections.singletonList(null));
This, however, throws an UnsupportedOperationException, which I'm assuming is because removeAll() is attempting to do some mutative operation on the immutable singleton collection. Is this correct?
If this is the case, what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?
Thanks in advance.
It works like a charm:
List<String> list = new ArrayList<String>();
list.add("abc");
list.add(null);
list.add("def");
list.removeAll(Collections.singletonList(null));
System.out.println(list); //[abc, def]
Indeed Collections.singletonList(null) is immutable (which is unfortunately hidden in Java[1]), but the exception is thrown from your list variable. Apparently it is immutable as well, like in example below:
List<String> list = Arrays.asList("abc", null, "def");
list.removeAll(Collections.singletonList(null));
This code will throw an UnsupportedOperationException. So as you can see singletonList() is useful in this case. Use it when client code expects a read-only list (it won't modify it) but you only want to pass one element in it. singletonList() is (thread-)safe (due to immutability), fast and compact.
[1] E.g. in scala there is a separete hierarchy for mutable and immutable collections and API can choose whether it accept this or the other (or both, as they have common base interfaces)
To answer your actual question :
what would be a typical use of this singletonList? To represent a collection of size 1 when you're sure you don't want to actually do anything with the collection?
The typical use is if you have one element and want to pass it to a method that accepts a List, ie
public void registerUsers(List<User> users) {...}
User currentUser = Login Manager.getCurrentUser();
registerUsers(Collections.singletonList(currentUser));
The removeAll() is a special case for this.
Has your list been protected with
Collections.unmodifiableList(list)
Because if you have protected it and try to modify it later you get that error.

Determining if a Java Iterable is ordered by contract

I am looking for a way to determine if a Collection (or maybe even any Iterable) is guaranteed to be ordered by its class contract.
I already know the Guava method : Ordering.natural().isOrdered(myCollection)
But this method is not relevant to my needs, because it checks if the values inside the collection are ordered. That's not what I need to determine, what I want to have is a isSorted method that will behave like this :
isSorted(new HashSet()) -> false
isSorted(new ArrayList()) -> true
etc...
What I am looking at would be typically implemented by checking the class of the collection, and comparing it to some kind of reference table of the collections which contract states that they are ordered, and only return true for these ones.
Do you know if something like this already exists in some library ?
You can do the following to determine if a collection is defined to be sorted.
collection instanceof SortedSet
There are three interfaces for ordered collections: List, SortedSet and SortedMap. You can check if your class is implementing one of them.
No, this doesn't exist in any library, and for good reason.
That library would have to know all the collection types that are flying around. If you're using Apache Commons Collections, it'd have to know about all of those. If you're using Guava, it'd have to know about all of those. If someone comes along and introduces a new collection type, you're now going to reject that type, even if it's ordered.
It doesn't make sense to provide that method in a library that can't know what other libraries you might have with whatever other collection types might be out there.
In an end application, it might make sense to implement it, with the heuristic techniques you've already been describing.
It might help if we knew what you were actually trying to do with this method.

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.

Why do people create arraylist like this?

Occasionally I see somebody create an arraylist like this, why?
List numbers = new ArrayList( );
Instead of:
ArrayList<something> numbers = new ArrayList<something>();
If you asking about using interface instead of concrete object, than it is a good practice. Imagine, you will switch to LinkedList tomorrow. In first case you won't need to fix variable declaration.
If the question was about non-using generics, then it is bad. Generics are always good as they give type safety.
What's good:
1. List is a general case for many implementations.
List trololo = new ListImpl();
Hides real implementation for the user:
public List giveMeTheList(){
List trololo = new SomeCoolListImpl();
return trololo;
}
By design it's good: user shouldn't pay attention to the realization. He just gets interface access for the implementation. Implementation should already has all neccessary properties: be fast for appending, be fast for inserting or be unmodifiable, e.t.c.
What's bad:
I've read that all raw types will be restricted in future Java versions, so such code better write this way:
List<?> trololo = new ListImpl<?>();
In general wildcard has the same meaning: you don't know fo sure will your collection be heterogenous or homogeneous?
Someday you could do:
List<something> numbers = new LinkedList<something>();without changing client code which calls numbers.
Declaring interface instead of implementation is indeed the rather good and widespread practice, but it is not always the best way. Use it everytime except for all of the following conditions are true:
You are completely sure, that chosen implementation will satisfy your needs.
You need some implementation-specific feauture, that is not available through interface, e.g. ArrayList.trimToSize()
Of course, you may use casting, but then using interface makes no sense at all.
The first line is old style Java, we had to do it before Java 1.5 introduced generics. But a lot of brilliant software engineers are still forced to use Java 1.4 (or less), because their companies fear risk and effort to upgrade the applications...
OK, that was off the records. A lot of legacy code has been produced with java 1.4 or less and has not been refactored.
The second line includes generics (so it's clearly 1.5+) and the variable is declared as an ArrayList. There's actually no big problem. Sure, always better to code against interfaces, so to my (and others) opinion, don't declare a variable as ArrayList unless you really need the special ArrayList methods.
Most of the time, when you don't care about the implementation, it's better to program to interface. So, something like:
List<something> numbers = new ArrayList<something>();
would be preferred than:
ArrayList<something> numbers = new ArrayList<something>();
The reason is you can tweak your program later for performance reason.
But, you have to be careful not to just choose the most generic interface available. For example, if you want to have a sorted set, instead of to Set, you should program to SortedSet, like this:
SortedSet<something> s = new TreeSet<something>();
If you just blatantly use interface like this:
Set<something> s = new TreeSet<something>();
Someone can modify the implementation to HashSet and your program will be broken.
Lastly, this program to interface will even be much more useful when you define a public API.
Two differences are that numbers in the first line is of type List, not ArrayList. This is possible because ArrayList is a descendant of List; that is, it has everything that List has, so can fill in for a List object. (This doesn't work the other way around.)
The second line's ArrayList is typed. This means that the second numbers list can only hold type something objects.

What are the implications of casting a generic List to a non-generic List?

I'm refatoring a home-grown DAO container, hoping to make the class generic. It internally uses an ArrayList to store the retrieved objects.
One usage of this class puts the container's list into a request scope, and due to a limitation of Websphere, I can't pass the generic List<Foo> to the request scope (Websphere doesn't handle generics out-of-the-box)
If I go ahead with my refactorings, I will need to convert/cast the List<Foo> into a non-generic List object..
// Boils down to this...
List<Foo> listFoo = new FooListing().findAllFoo();
List listThings = listFoo;
request.setAttribute("listThings", listThings);
What are the implications of reversing a generification like this? Should I avoid doing this kind of manipulation?
EDIT: The code snippet is verbose to explicitly demonstrate what I'm describing..
If the component type of the List does match the expected type, there is no problem.
Generics in Java are only used for type-checks by the compiler, they have not effect at runtime. If you are using an older library that does not support generics, you have no choice but to ignore the generic type.
Things should continue to work, as this system has been designed with backwards compatibility in mind.
So all you are losing is the compile-time type checking (it puts you back to where Java was at 1.4, which means, if the types match, everything will work, if not, you'll get ClassCastExceptions or other unwanted behaviour at runtime).
However, I think you can just write
request.setAttribute("listThings", listFoo);
This method takes any kind of Object. Even if it wanted a List, you could still pass a List<Foo> (which is still a List).
Java uses "type erasure" for generics -- essentially that means that the compiler checks the generics, but the runtime forgets all about it and just treats it as a list of objects.*
Whenever you treat a List<Foo> as just a List, you won't get compiler checks to make sure you don't put a Bla into your list. So you could get a ClassCastException if you call List<Foo>.get() and it turns out to be a Bla hiding in the list. But that can only happen if you some code puts a Bla in your list.
If you wan't to be cautious, then if you pass the List<Foo> as a List to anything that might add a non-Foo to the list, don't treat it as a List<Foo> whenever you access it, but treat it as a list of Objects and add instanceof checks.
*Some of the information is accessible at runtime, but let's not complicate matters.
A "non-generic" version of a generic type is called a "raw type".
Passing a generic type where the raw equivalent is requested is generally ok. This is actually the main reason generics in Java work the way they do (with erasure): to enable interoperability between "generified" code and pre-generics code.
The main thing you need to be careful about is that if you pass a List<Foo> to something that askes for a List, they may put non-Foo objects into the List. You won't get any compile time checking to help you here. You do get some runtime checks: a ClassCastException will be thrown when you use a method that returns a Foo on your List<Foo> and it has to return a non-Foo.
If you want more fail-fast behavior you can wrap your List<Foo> with Collections.checkedList() to get a List that'll check the type of elements on insertion.
Things get more complicated if Foo itself is a generic type. Runtime checks are only done on reified types (ie: the type with generic type parameters removed) so if you give them a List<Set<Bar>> and they insert a Set<Baz> or just a Set, you won't know since the runtime/reified type of the element is Set either way.
First, you can't cast a generic to a non-generic list so yeah you'd have to convert it.
Second, the two main advantages to a generic list are 1) it ensures that all objects are of the specified type and 2) it allows you to directly access methods of the object collection without needing to recast them. This allows you to write cleaner code and saves some processing cycles from having to cast back and fourth.
Neither one of these advantages is a dire need however. If you can't use them you won't notice a difference in performance. Your code may look a little messier though.
I have similar problems with Weblogic Portal. Just use none-generic type for this case.

Categories

Resources