4

I know there are builtin routines, but as a learner, I want to sort using my own devices, and since sorting is old hat, I decided to try to make my own generic sort routine that I could use for numbers or strings and maybe even dates, if I ever figure out how they work in Java.

So here's what I have, having traded one error for another for another until now I only have errors in two places (enclosed within "**" markers), with need to figure out how to compare.

package sort;
import java.util.ArrayList;

public  abstract class Sort<E> implements Comparable<E> {

   public void swap(ArrayList<E> a, int i, int j) {
    E c = a.get(i);
    a.set(i,a.get(j));// = a[j];
    a.set(j, c);
  }

  public void bubbleSort(ArrayList<E> a) {
    boolean inOrder = false;
    while (!inOrder) {
      inOrder = true;
      for (int i = 1; i < a.size(); i++) {
        **if( a.get(i - 1).compareTo(a.get(i)) > 0 )** {
//cannot find symbol: method compareTo(E); location: class Object
//where E is a type-variable: E extends Object declared in class Sort                 
      inOrder = false;
          swap(a, i, i - 1);
        } 
      }
    }
  }

  public static void main(String args[]) //hadda lose 'static' for 'setLayout' to work
  {
    ArrayList<Integer> ary = new ArrayList<>();
    ary.add(2); ary.add(4); ary.add(7); ary.add(3);
    **bubbleSort(ary)**;
//method bubbleSort in class Sort<E> cannot be applied to given types; 
//required: ArrayList<E>
//found: ArrayList<Integer>
//reason: actual argument ArrayList<Integer> cannot be converted to ArrayList<E> 
//by method invocation conversion where E is a type-variable:
//E extends Object declared in class Sort
    for (int i = 0; i < ary.size(); i++) {
      System.out.println(ary.get(i));
    }
  }

  @Override
  public int compareTo(E o) {
    **return 0;** // fixing errors above may help this fall into place
  }
}

I'm trying to learn things that I feel ready for only to find that I'm not quite ready; close, cigarless.

DSlomer64
  • 4,234
  • 4
  • 53
  • 88
  • 1
    May I sugges that, as a learner, you learn better sorting algorithms than bubble-sort? – millimoose Sep 29 '13 at 23:38
  • Also, if `bubbleSort()` is an instance method, you probably want `new Sort().bubbleSort(ary);` If it's a static method, you'll need to pass the type parameter around explicitly on the methods themselves, by declaring the method as `public static > bubbleSort(ArrayList a) {...}`, instead of putting the type parameter on the `Sort` class which only acts as a namespace in this case. – millimoose Sep 29 '13 at 23:40
  • 1
    You are thoroughly misunderstanding generics. – SLaks Sep 29 '13 at 23:40
  • It is however completely beyond me why `Sort implements Comparable`. You probably meant to make `E` *bounded*: http://docs.oracle.com/javase/tutorial/java/generics/bounded.html – millimoose Sep 29 '13 at 23:42
  • Ontop of ruak answer, `Sort` is `abstract`, it can not be instantiated, meaning that you will never be able to execute the `bubbleSort` method until you have a concrete implementation. Based on you code, I don't any point to make this class `abstract` – MadProgrammer Sep 29 '13 at 23:44
  • 1
    May I also suggest that you don't sort Collections, you sort arrays? You've chosen one of the most inefficient sorting algorithms known to computer science and you're applying it in one of the worst possible ways. – user207421 Sep 30 '13 at 03:31
  • I'm a learner of JAVA. I've implemented Quicksort and Shellsort (to name two) in the past. But since swapping gave me fits 2 months ago, I decided to use Bubblesort as my choice to keep Java-implementation problems to a minimum. Only 3's pretty minimal. And, yes, I AM totally misunderstanding generics, hence my plea for help, which you didn't give, Slaks, so cut me some! I read/reviewed plenty last night; let's see where what I found leads, along with the link supplied by millimoose. Sheeeesh! – DSlomer64 Sep 30 '13 at 14:27

3 Answers3

4

This:

public  abstract class Sort<E> implements Comparable<E> {

means that E is an arbitrary object type, and that instances of Sort<E> can be compared to instances of E. (So your error message is complaining that E.compareTo doesn't exist, since Object doesn't have such a method.) What you want is this:

public abstract class Sort<E extends Comparable<E>> {

which means that E must be a type whose instances can be compared to each other.


Edited to add: Actually, as SLaks together point out, there's no real reason for Sort to be generic; you just need the bubbleSort method to be generic. Further, as MadProgrammer implies, either Sort should be non-abstract (so you can instantiate it directly) or bubbleSort should be static (so it can be called without instantiating a Sort instance) or both. For example:

public class Sort {
    private static <E> void swap(ArrayList<E> a, int i, int j) {
        ...
    }

    private static <E extends Comparable<E>> void bubbleSort(ArrayList<E> a) {
        ...
    }

    ...
}

Better yet, Sort can be an interface with a sort method, and BubbleSort.sort(...) is just an implementation of it (rather than giving Sort a specific bubbleSort method).

ruakh
  • 175,680
  • 26
  • 273
  • 307
1

I'd like to just make a comment, if I may.

Learning BubbleSort is a fine way to learn how to use data structures in Java. I agree with the others that, in the real world, you will never use BubbleSort because it offers the worst performance of any sorting algorithm with the exception of "StoogeSort".

Still, there is value in going through the exercize as a new learner if it teaches you how to do important things like use and apply a generic type parameter, work with control-flow statements (e.g. for loops), and even do exception handling. Don't listen to the naysayers. The principle advantage of Bubblesort is that the algorithm is simple.

In my view, an even simpler sorting algorithm is the "Delayed Replacement Sort" also known as the "Selection Sort". The Delayed Replacement Sort has the same bad time complexity as BubbleSort (O(n^2)) but unlike BubbleSort, Selection Sorting is still used in certain applications. It is incorporated as a subalgorithm in some optimized sorting algorithms, and because it minimizes the number of swaps needed to order the collection, Selection Sort is still used when the cost of performing a swap is high.

The pseudocode for the Delayed Replacement Sort follows and is, in my opinion, even simpler than BubbleSort:

Begin DELAYEDSORT
 For ITEM=1 to maximum number of items in list-1
    LOWEST=ITEM
    For N=ITEM+1 to maximum number of items in list
       Is entry at position N lower than entry at position LOWEST?
          If so, LOWEST=N
    Next N
    Is ITEM different from LOWEST
       If so, swap entry at LOWEST with entry in ITEM
 Next ITEM
End DELAYEDSORT

The Delayed Replacement Sort can be as much as 50% faster than BubbleSort but still should not be used to sort very large collections.

scottb
  • 9,908
  • 3
  • 40
  • 56
  • scottb is correct--as a learner of Java (not optimal sorting), bubblesort did help me overcome what likely would have been overwhelmingly many errors; now he's making me want to employ his p-code or maybe implement quicksort since recursion is pretty danged cool. (Also cool: its animations at en.wikipedia.org/wiki/Quicksort) – DSlomer64 Oct 03 '13 at 23:25
  • @DSlomer64: Check out the animation for "Stooge Sort" at wikipedia. It's a hoot. – scottb Oct 05 '13 at 04:31
  • @scottb--Did you notice this: "The algorithm gets its name from slapstick routines of the Three Stooges, in which each stooge hits the other two.[citation needed]" I'm wondering if the citation needed would be to confirm the reason for the naming of the routine or to confirm that, indeed, there exists an episode in which Moe slaps Larry and Curly and Larry slaps Moe and Curly and Curly slaps Larry and Moe, and if so, by title or what?? (I imagine multiple such episodes exist.) – DSlomer64 Oct 08 '13 at 02:38
0

After taking SLaks' advice and becoming much more familiar with generics (made generic stack and queue classes yesterday), today I used ruakh's outline (but had to change private to public in "bubblesort" line) which enabled majorly changing main to something sane (which now boils down to one do-something-useful line Sort.bubbleSort(ary);) and it worked, but I have two burning questions:

(1) What exactly does the first <E> mean/do/imply in this line:

private static <E> void swap(ArrayList<E> a, int i, int j) {

(2) Similarly... what's up with <E extends Comparable<E>> here:

private static <E extends Comparable<E>> void bubbleSort(ArrayList<E> a) {

To answer my own question, "Now, why didn't I think of those?"... "Why WOULD I think of them??"

EDIT: "parameterized" or "generic" methods are as legal as parameterized/generic types, and why not?

But I still don't know why, "obviously legal" or not, I'd have thought of either "trick".

EDIT: One word: experience

DSlomer64
  • 4,234
  • 4
  • 53
  • 88