Just another code snippet



  • Thought I'd share the pain with the Java coders out there. Don't know if this particular gem came from the American developers who aren't involved any more, or the Ukrainian ones who I'm currently "co-developing" with. I suspect the former, as the latter seem to be allergic to comments.

      static void sort(Set<SearchResult> col, Comparator comp) {
        // inefficient but effective way to circumvent generics
        SearchResult[] results = new SearchResult[col.size()];
        results = col.toArray(results);
        Arrays.sort(results, comp);
        col.clear();
        col.addAll(Arrays.asList(results));
      }
    

    Yes, they sort the data, and the put in to a collection that doesn't guarantee ordering.



  • Maybe it was an "optimisation"?

    The set guarantees no duplicates (which usually means it is sorted for efficiency), so inserting sorted data might be faster than inserting randomly ordered data... That kind of "optimisation" should definately be explained with a comment though... and justified with a benchmark...



  • @roy said:

    circumvent generics

    As long as we are talking about Java, this seems like a good reason to me.



  • @Farmer Brown said:

    @roy said:
    circumvent generics

    As long as we are talking about Java, this seems like a good reason to me.

    And you have the guts to accuse other people of trolling? The only reason I can see for you posting this is just to have a bash at Java. It's been done (and is currently being done) far better and with actual evidence to back them up by other people.



  • @ActionMan said:

    Maybe it was an "optimisation"?

    The set guarantees no duplicates (which usually means it is sorted for efficiency), so inserting sorted data might be faster than inserting randomly ordered data...

     

     Ah, but if you look again you'll find that the things which are inserted into the set are obtained by extracting them from the set. After first creating an empty array which is immediately discarded.



  • @pjt33 said:

    After first creating an empty array which is immediately discarded.
    Actually, toArray(T[]) only creates a new array if the given is not large enough:

    @Java 1.6 API Specification said:

    Returns an array containing all of the elements in this set; the runtime type of the returned array is that of the specified array. If the set fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this set.

    Of course, it is still useless that the array is created explicitly before the call when they could just have said toArray(new SearchResult[0]).



  • @roy said:

    Don't know if this particular gem came from the American developers who aren't involved any more, or the Ukrainian ones who I'm currently "co-developing" with.

    TRWTF is that you don't use version control?  SVN is even honest enough to provide 'blame' as a synonym for 'annotate'...



  • @Flatline said:

    And you have the guts to accuse other people of trolling? The only reason I can see for you posting this is just to have a bash at Java. It's been done (and is currently being done) far better and with actual evidence to back them up by other people.

    Ignore him.  He's a troll is the most classic sense of the word; he's trying to bait people into arguments and he persists in verbally attacking forum members, including several completely off-topic and random bits of flamebait targeted at me.  He's just trying to derail the threads with flaming and the best thing you can do is look the other way. 



  • @Flatline said:

    And you have the guts to accuse other people of trolling? The only reason I can see for you posting this is just to have a bash at Java. It's been done (and is currently being done) far better and with actual evidence to back them up by other people.

    Are you actually supporting Java generics?

    You talk about 'evidence' but provide none, so I suspect you are just having an emotional response to someone implying that Java might not be as great as you want to think it is.



    Java generics sucking is a well known, well accepted fact of life. Anyone who has used them wouldn't ask for 'evidence'. However, here are two sources that can explain this to you, instead of me trying to argue this out with you:

    http://www.facsim.org/node/77





  • @morbiuswilters said:

    he's trying to bait people into arguments and he persists in verbally attacking forum members, including several completely off-topic and random bits of flamebait targeted at me.  He's just trying to derail the threads with flaming and the best thing you can do is look the other way.

    Boy, oh boy, someone must have kicked you around a whole lot in life for you to be this sensitive.

    Apparently you have never experienced Java generics...



  • @Farmer Brown said:

    Apparently you have never experienced Java generics...
    I have. They're amazingly cool. Read the book, and be educated. Then die in a fire like the troll that you are.
    (By the way, I read the links you gave earlier. Yeah, if you're coding to an API like Servlet, and use typed collections classes in your code, you get warnings when unboxing them, because the JVM doesn't know about generic type information, only the compiler does. But if you're writing new code with little to no legacy interaction, or writing an API for future code to use, generics are incredibly helpful compared to regular collections classes because so long as everyone follows the generics rules your List<Widget> will only have Widgets, no matter what other (compliant) code uses it.)

     

     



  •  You know, I'm not convinced yet.  It would be nice to know what the underlying set is.  Suppose it's a LinkedHashSet.  Then the iteration order of the set is the order in which the items are inserted.  So this could be creating a new ordering (iteration order) for the set, with the ordering rule supplied by the comparitor.  Sure, there might be an easier way of doing this, but I'd have to study the code *and* the API more to make sure that I'm improving it.



  • @TwelveBaud said:

    Then die in a fire like the troll that you are.

    The best way to deal with trolls is to ignore them while "sacrificing" some primo bud to ammoQ. 



  • @TwelveBaud said:

    I have. They're amazingly cool.

    Well that just says it all then.



  • @AltSysrq said:

    @pjt33 said:

    After first creating an empty array which is immediately discarded.
    Actually, toArray(T[) only creates a new array if the given is not large enough:

    @Java 1.6 API Specification said:

    Returns an array containing all of the elements in this set; the runtime type of the returned array is that of the specified array. If the set fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this set.

    Of course, it is still useless that the array is created explicitly before the call when they could just have said toArray(new SearchResult[0]).

     

     I don't see your reasoning here.  In the code presented, only one array is ever created, and it is created at the proper size the first time.  The "toArray" call merely fills in the members by copying element references, then returning the original array reference.  If instead you call toArray(new SearchResult[0]) the SearchResult[0] array object you created will be thrown away and a second array of the proper size will be created, but you will have created the zero-length array object needlessly.

    In fact, I'm going on record here to say that this *is* good code, and I'd be very happy to have it in my codebase.  It is certainly true that more commenting would be of benefit, in particular about the mystic properties of LinkedHashSet, but we don't know what the development plan was for commenting.  Perhaps it's all kept in a design document.

    A scenario where you might use this code:

    - A JSF application gets a result set back from the database persistence layer, say a list of Employee objects satisfying a certain query.

    - It converts the result set to a LinkedHashSet.  This Set implementation has the useful property that the iteration order is the insertion order into the set.

    - The results are sorted in whatever display order originally requested by calling this routine with the proper Comparator.

    - The result set is then passed to the JSF View, which uses a JSF h:datatable component to display the information, in iteration order, which retains the ordering imposed by the sort.

    - The user wants a different order, so he/she clicks a button -- the JSF application justs calls this routine with the original result set and a different comparator and redisplays.



  • Anybody complaining about Generics just doesn't use Java, plain and simple.  Farmer Brown, you said yourself that you don't even have the JVM installed on your machine, which renders you useless for this conversation.  The fact is all Generics do is allow for type safty at compile time (depending on your IDE at the time of typing).  That's it.  Instead of getting a type cast exception at run time you will know before compiling, or at compile time, whether or not it is a valid statement. Please explain how this is a bad thing?  If you don't want to use Generics perform a @SuppressWarnings("unchecked").  That's what it is there for.



  • @amischiefr said:

    Anybody complaining about Generics just doesn't use Java, plain and simple.  Farmer Brown, you said yourself that you don't even have the JVM installed on your machine, which renders you useless for this conversation.  The fact is all Generics do is allow for type safty at compile time (depending on your IDE at the time of typing).  That's it.  Instead of getting a type cast exception at run time you will know before compiling, or at compile time, whether or not it is a valid statement. Please explain how this is a bad thing?  If you don't want to use Generics perform a @SuppressWarnings("unchecked").  That's what it is there for.

     

    Apparently you have never heard of better parametrically polymorphic type systems. I should remind you again, amischiefr, that Java is a half-ass language. TRWTF is that Java took this long to implement parametric polymorphism, and even then implemented it lamely.



  • A set does not garantee any particular order. So the coder is just dumb.

    Or they can use a TreeSet which garantees order. DUH! http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeSet.html and look its 1.4.2 not some fancy shmancy java 6 construct!



  • @HypocriteWorld said:

    @amischiefr said:

    Anybody complaining about Generics just doesn't use Java, plain and simple.  Farmer Brown, you said yourself that you don't even have the JVM installed on your machine, which renders you useless for this conversation.  The fact is all Generics do is allow for type safty at compile time (depending on your IDE at the time of typing).  That's it.  Instead of getting a type cast exception at run time you will know before compiling, or at compile time, whether or not it is a valid statement. Please explain how this is a bad thing?  If you don't want to use Generics perform a @SuppressWarnings("unchecked").  That's what it is there for.

     

    Apparently you have never heard of better parametrically polymorphic type systems. I should remind you again, amischiefr, that Java is a half-ass language. TRWTF is that Java took this long to implement parametric polymorphism, and even then implemented it lamely.

     

     

    Java generics can get pretty out-of-hand! They are nice in a few situations to just note what object is being used by a list or w/e. They are often overused in many frameworks. Implemented poorly too! If I have the following class heirarchy generics fail:

    class Foo{}

    class Bar extends Foo{}

    method1(List<Foo> var1){}

    List<Bar> barlist = ...

    method1(barlist)

     

    This is a compile-time error. It does not know that Bar is actually a child of foo and this is a safe operation. To call method 1 with barlist as an argument I must cast to a non-generic version, since you can't cast to generics!

    method1((List) barlist)

     

    This invokes the non-generics mechanism where barlist is treated as a non-generic using class and the generic part of method1's paramater is ignored when compiling the code.

    Bah what crap! I mean if they implement something at least they can do it well, even if not in a perfect language.



  • @astonerbum said:

    Java generics can get pretty out-of-hand! They are nice in a few situations to just note what object is being used by a list or w/e. They are often overused in many frameworks. Implemented poorly too! If I have the following class heirarchy generics fail:

    class Foo{}

    class Bar extends Foo{}

    method1(List<Foo> var1){}

    List<Bar> barlist = ...

    method1(barlist)

     

    This is a compile-time error. It does not know that Bar is actually a child of foo and this is a safe operation. To call method 1 with barlist as an argument I must cast to a non-generic version, since you can't cast to generics!

    method1((List) barlist)

     

    This invokes the non-generics mechanism where barlist is treated as a non-generic using class and the generic part of method1's paramater is ignored when compiling the code.

    Bah what crap! I mean if they implement something at least they can do it well, even if not in a perfect language.

     

     

    I'm not here to defend Generics in Java, but your clearly doesn't understand it very well.  To use generics correctly in your example, your method should be:

    <T extends Foo> method1(List<T> var1){}

     Go through some tutorials before bashing something you don't even know how to use.



  • @amischiefr said:

    Anybody complaining about Generics just doesn't use Java, plain and simple.  Farmer Brown, you said yourself that you don't even have the JVM installed on your machine, which renders you useless for this conversation.  The fact is all Generics do is allow for type safty at compile time (depending on your IDE at the time of typing).  That's it.  Instead of getting a type cast exception at run time you will know before compiling, or at compile time, whether or not it is a valid statement. Please explain how this is a bad thing?  If you don't want to use Generics perform a @SuppressWarnings("unchecked").  That's what it is there for.

    The point isn't that generics are a bad thing, it's that Java's generics, despite the huge improvement over Java without generics, still rates poorly compared to other languages.


  • @bstorer said:

    The point isn't that generics are a bad thing, it's that Java's generics, despite the huge improvement over Java without generics, still rates poorly compared to other languages.

     

    Well sure, I can respect that.  The problem that I have with all of the Java bashing is that it really is on the same level as Windows bashing.  I have never, and will never claim that it is the best language out there, just that it is not a piece of shit and that it does serve many purposes.  There is nothing wrong with writting a nice little eSomething web application in Java.  It's efficient if done right and very easy to code/maintain.  



  • @amischiefr said:

    @bstorer said:

    The point isn't that generics are a bad thing, it's that Java's generics, despite the huge improvement over Java without generics, still rates poorly compared to other languages.

     

    Well sure, I can respect that.  The problem that I have with all of the Java bashing is that it really is on the same level as Windows bashing.  I have never, and will never claim that it is the best language out there, just that it is not a piece of shit and that it does serve many purposes.  There is nothing wrong with writting a nice little eSomething web application in Java.  It's efficient if done right and very easy to code/maintain.  

    And Java bashers (like myself) are not claiming Java is the worst language and everyone should write all software in ML. It's just for pointing out simple improvements that could be made to our currently most-popular PL so our software could have be written easier with less bugs and resource costs, and less likely to appear as a TDWTF feature article.

    Peace.



  • @astonerbum said:

    A set does not garantee any particular order. So the coder is just dumb.

    Or they can use a TreeSet which garantees order. DUH! http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeSet.html and look its 1.4.2 not some fancy shmancy java 6 construct!

     

    Yeah, fine.  Sorted by the class's natural order.  So then the user wants to see things in another order.  Whaddaya gonna do?  Redefine the element class on the fly?  You've proven you can check out an API, now check out LinkedHashSet, reread my previous post, and learn something.

    And yes, you can construct another set with a different Comparator, but then you're using a different object, aren't you?


Log in to reply