Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 13 of 13

Thread: Collection.sort problem

  1. #1
    Junior Member
    Join Date
    Sep 2010
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Collection.sort problem

    Hi I'm having problems with java and the collections.sort method. I can't figure out how to sort an arraylist using the compareTo and Comparable interface. I've created the compareTo method and so on, but how do I sort an arraylist in another class.

    I have created a book class and a CollectionOfBooks class, and implemented the Comparable in Book-class. But how do I sort the CollectionOfBooks arraylist?

    When I try to sort it, it gives me the error "The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the arguments"

    From what I understand, the Collection.sort uses a List and then takes as arguments the list that is to be sorted and then what comparable-method to be used?

    I've added the code below to clarify what i mean =)

    package se.kth.labb3b;
     
    import java.io.BufferedInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInput;
    import java.io.ObjectInputStream;
    import java.io.Serializable;
    import java.util.List;
    import java.util.Scanner;
     
    public class UserInterface implements Serializable {
     
    	public static void main(String[] args) {
    		UI ui = new UI();
    		int running = 1;
     
    	    //note the use of abstract base class references
     
    	    try{
    	      //use buffering
    	      InputStream file = new FileInputStream( "books.dat" );
    	      InputStream buffer = new BufferedInputStream( file );
    	      ObjectInput input = new ObjectInputStream ( buffer );
    	      try{
    	        //deserialize the List
    	        List<Book> recoveredBooks = (List<Book>)input.readObject();
    	        //display its data
    	        for(Book book: recoveredBooks){
    	          System.out.println("Recovered books: " + book);
    	          ui.readBook(book);
    	        }
    	      }
    	      finally{
    	        input.close();
    	      }
    	    }
    	    catch(ClassNotFoundException e){
    	      e.printStackTrace();
    	    }
    	    catch(IOException e){
    	      e.printStackTrace();
    	      System.out.println("File books.dat wasn't found!");
    	    }
     
     
    		while (running == 1) {
    			System.out.println("\nWelcome to Lars and Daniels bookrecord!\n\n" + 
    					"1) Add a new book\n" + 
    					"2) List all objects\n" +
    					"3) Search\n" +
    					"4) Write to file");
     
    			Scanner scan = new Scanner(System.in);
    			int answer = scan.nextInt();
    			switch (answer) {
    			case 1:
    				ui.addBook();
    				break;
    			case 2:
    				ui.getAllBooks();
    				break;
    			case 3:
    				System.out.print("Search title: ");
    				//ui.getBooksByTitle(scan.nextLine());
    				break;
    			case 4:
    				ui.writeToFile();
    				break;
    			default:
    				System.out.println("Fail");
    				running = 0;
    				break;
     
    			}
    		}
     
    	}
    }

    package se.kth.labb3b;
     
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutput;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
     
     
    public class UI implements Serializable {
     
    	Book books;
    	CollectionOfBooks cob = new CollectionOfBooks();
     
    	public void addBook() {
    		System.out.print("Book name: ");
    		Scanner scan = new Scanner(System.in);
    		String bookName = scan.nextLine();
    		System.out.print("ISBN: ");
    		int isbn = scan.nextInt();
    		System.out.print("Edition: ");
    		int edition = scan.nextInt();
    		System.out.print("Price: ");
    		double price = scan.nextDouble();
    		ArrayList<Author> lista = new ArrayList<Author>();
    		System.out.print("Numbers of authors: ");
    		int numberOfAuthors = scan.nextInt();
    		for (int i = 0; i <= numberOfAuthors; i++) {
    			System.out.println("Author: ");
    			lista.add(new Author(scan.nextLine()));
    		}
    		books = new Book(bookName, isbn, edition, price, lista);
    		cob.addBook(books);
     
    	}
     
    	public void readBook(Book book){
    		cob.addBook(book);
    	}
     
    	/*public void getBooksByTitle(String bookname) {
    		List<Book> temp = cob.remoteSort();
    		Collections.sort(temp);
    		System.out.println("Book:");
    		String tempbook = Collections.binarySearch(temp, bookname);
    		System.out.println(tempbook);
     
    	}*/
     
    	public void getAllBooks() {
    		System.out.println("Book titles:");
    		for (int j = 0; j < cob.getNumberOfBooks(); j++) {
    			System.out.print(cob.toString(j));
    		}
     
    	}
     
    	public void writeToFile(){
    		List<Book> temp = cob.remoteSort();
    	    try{
    	        //use buffering
    	        OutputStream file = new FileOutputStream( "books.dat" );
    	        OutputStream buffer = new BufferedOutputStream( file );
    	        ObjectOutput output = new ObjectOutputStream( buffer );
    	        try{
    	          output.writeObject(temp);
    	        }
    	        finally{
    	          output.close();
    	        }
    	      }  
    	      catch(IOException e){
    	        e.printStackTrace();
    	      }
     
    	}
     
    }

    package se.kth.labb3b;
     
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
     
    public class CollectionOfBooks {
     
    	private ArrayList<Book> Books = new ArrayList<Book>();
     
    	public void addBook(Book book) {
    		Books.add(book);
    	}
     
    	public void removeBook(Book book) {
    		Books.remove(book);
    	}
     
    	public int getNumberOfBooks() {
    		return Books.size();
    	}
     
    	public ArrayList<Book> getBooksByTitle(String title) {
    		return Books;
    	}
     
    	public ArrayList<Book> remoteSort(){
    		return Books;
    	}
     
    	public String toString(int i){
    		String back;
    		back = ("Title: " + Books.get(i).getTitle());
    		back = back + "\nISBN: " + Integer.toString(Books.get(i).getIsbn());
    		back = back + "\nRevision: " + Integer.toString(Books.get(i).getEdition());
    		back = back + "\nPrice: " + Double.toString(Books.get(i).getPrice());
    		back = back + "\nAuthor: \n";
    		ArrayList<Author> author = Books.get(i).getAuthors();
    		for(int j = 0; j < author.size(); j++){
    			back = back + "\t" + author.get(j).getAuthor() + "\n";
    		}
    		System.out.println("*****************************************************'");
    		return back;
    	}
    }

    package se.kth.labb3b;
     
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.Collections;
     
    public class Book implements Comparable<Book>, Serializable {
     
    	private String title;
    	private int edition, isbn;
    	private double price;
     
    	private ArrayList<Author> Author = new ArrayList<Author>();
     
    	public Book(String title, int isbn, int edition, double price, ArrayList<Author> Author) {
    		this.title = title;
    		this.isbn = isbn;
    		this.edition = edition;
    		this.price = price;
    		this.Author = Author;
    	}
     
    	public void sortArray(Book n){
    		Collections.sort(n, title);
    	}
     
    	public String getTitle() {
    		return title;
    	}
     
    	public int getIsbn() {
    		return isbn;
    	}
     
    	public int getEdition() {
    		return edition;
    	}
     
    	public double getPrice() {
    		return price;
    	}
     
    	public ArrayList<Author> getAuthors() {
    		return Author;
    	}
     
    	public int compareTo(Book objekt) {
          if (objekt.getTitle().compareTo(this.getTitle()) < 0){
        	  return 0;
          }else{
        	  return 1;
          }
        }
     
     
    }

    package se.kth.labb3b;
     
    import java.io.Serializable;
     
    public class Author implements Serializable {
    	private String name;
     
    	public Author(String n){
    		name = n;
    	}
     
    	public String getAuthor(){
    		return name;
    	}
    }

    Would really appreciate some help =)


  2. #2
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Collection.sort problem

    I haven't used Comparable extensively, but I'll provide what help I can.

    The line where you are sorting is this, correct:
    Collections.sort(temp);

    If so, you seem to be attempting to use this version of the Collection's Sort Method:
    sort

    public static <T extends Comparable<? super T>> void sort(List<T> list)

    Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

    This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.

    The specified list must be modifiable, but need not be resizable.

    The sorting algorithm is a modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n log(n) performance. This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array. This avoids the n2 log(n) performance that would result from attempting to sort a linked list in place.

    Parameters:
    list - the list to be sorted.
    Throws:
    ClassCastException - if the list contains elements that are not mutually comparable (for example, strings and integers).
    UnsupportedOperationException - if the specified list's list-iterator does not support the set operation.
    See Also:
    Comparable
    Confirm this for me and I'll attempt to look into this further.

  3. #3
    Junior Member
    Join Date
    Sep 2010
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Collection.sort problem

    It is correct, however I see that the error is that i only pass the List to be sorted and not what method to be used with comparable. So it should look something like this:

    Pseudo-code:
    Collections.sort(temp, compareTo);

    Otherwise I won't be able to sort the books based on title.

    from Book.java
    public int compareTo(Book objekt) {
          if (objekt.getTitle().compareTo(this.getTitle()) < 0){
        	  return 0;
          }else{
        	  return 1;
          }
        }


    So my problem remains, i'm not sure how to implement the code so it tells java to sort with the given compareTo method.

  4. #4
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Collection.sort problem

    That is incorrect. There are two sort methods in the Collections API:
    1:
    sort

    public static <T> void sort(List<T> list,
    Comparator<? super T> c)

    Sorts the specified list according to the order induced by the specified comparator. All elements in the list must be mutually comparable using the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

    This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.

    The sorting algorithm is a modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n log(n) performance. The specified list must be modifiable, but need not be resizable. This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array. This avoids the n2 log(n) performance that would result from attempting to sort a linked list in place.

    Parameters:
    list - the list to be sorted.
    c - the comparator to determine the order of the list. A null value indicates that the elements' natural ordering should be used.
    Throws:
    ClassCastException - if the list contains elements that are not mutually comparable using the specified comparator.
    UnsupportedOperationException - if the specified list's list-iterator does not support the set operation.
    See Also:
    Comparator
    2:
    sort

    public static <T extends Comparable<? super T>> void sort(List<T> list)

    Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

    This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.

    The specified list must be modifiable, but need not be resizable.

    The sorting algorithm is a modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n log(n) performance. This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array. This avoids the n2 log(n) performance that would result from attempting to sort a linked list in place.

    Parameters:
    list - the list to be sorted.
    Throws:
    ClassCastException - if the list contains elements that are not mutually comparable (for example, strings and integers).
    UnsupportedOperationException - if the specified list's list-iterator does not support the set operation.
    See Also:
    Comparable
    Now, there are two different classes that have similar names. 1 is the Comparable Class and the other is the Comparator Class.

    From the two methods above, the first uses the Comparator Class and the second uses the Comparable Class.

    Now, in Book, you implemented the Comparable Class. Which means you shouldnt use the first method to Compare. Even so, this parameter: Comparator<? super T> c means it requires a Comparator Object, not a method. It is very confusing, I know.

    Basically, all Objects can be compared somehow. By implementing the Comparable Class, you have to Override the compareTo method and tell the program how each Object is going to be compared. Once you have specified how you want them compared, you can use the sort method #2, where you send it the List and it uses the indicated compareTo method to sort the List.

    Now, if you do not implement the Comparable Class but you still want to compare two Objects, you can create something called a Comparator Object. The Comparator Interface requires you to have a compareTo method and an equals method. Once you have specified those, you can compare your objects. This means you have to use sort method #1, where you send it the List and the Comparator Class that you create, where it uses the indicated compareTo and equals methods to sort the List.

    Tell me if that makes sense.

  5. #5
    Junior Member
    Join Date
    Sep 2010
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Collection.sort problem

    Ah yes this is confusing =/

    But since I do use the Comparable class with:
    public class Book implements Comparable<Book>

    I can't see the problem by using
    List<Book> temp = cob.remoteSort();
    		Collections.sort(temp);
    ...
    the "temp" is defined as a List and public static <T extends Comparable<? super T>> void sort(List<T> list) want a list to sort...

    Can the problem be that my object consists of Strings and ints etc and when i want to sort by book title it goes wrong there?

    I do feel really lost

  6. #6
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Collection.sort problem

    Here is a possibility:
    The compareTo method is supposed to return a -1,0,or 1. However, in your compareTo method, you only return a 0 and a 1. I do not know if it will make a difference, but it is worth a try. Attempt to revise your compareTo method to have a condition where it will return -1 (an indication that something is less than something else).

    Here is how the compareTo method says it should works:
    Where x is the result returned:
    x < 0 == Object is Less Than Parametrized Object
    x = 0 == Object is Equal To Parametrized Object
    x > 0 == Object is Greater Than Parametrized Object

  7. #7
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Collection.sort problem

    Don't create your own collection class, there's already one which exists.

    Simply create your list of comparable objects and pass them to your algorithm.

    Here's a simple example:

    // Book class
    // sort books by their name
    public class Book implements Comparable<Book>
    {
        public String name;
        public Book(String name)
        {
            this.name = name;
        }
     
        public String toString()
        {
            return name;
        }
     
        public int compareTo(Book other)
        {
            return this.name.compareTo(other.name);
        }
    }

    public class TestSort
    {
        public static void main(String[] args)
        {
            ArrayList<Book> list = new ArrayList<Book>();
            list.add(new Book("Multi-threading"));
            list.add(new Book("Intro to Java"));
            list.add(new Book("Swing"));
            list.add(new Book("AWT"));
            list.add(new Book("JNI"));
            System.out.println("Unsorted list: " + list);
            Collections.sort(list);
            System.out.println("Sorted list: " + list);
        }
    }

  8. The Following User Says Thank You to helloworld922 For This Useful Post:

    Minken (September 21st, 2010)

  9. #8
    Junior Member
    Join Date
    Sep 2010
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Collection.sort problem

    Rewrote the comparable code to:
    public int compareTo(Book objekt) {
    		if (objekt.getTitle().compareTo(this.getTitle()) < 0) {
    			return 0;
    		} else if (objekt.getTitle().compareTo(this.getTitle()) > 0) {
    			return -1;
    		} else {
    			return 1;
    		}
    	}

    And wrote in CollectionOfBooks.java
    private List<Book> Books = new ArrayList<Book>();
     
    	public void addBook(Book book) {
    		Collections.sort(Books);
    		Books.add(book);
    	}

    So that Books is a List and that as soon as you add a book to the list the list should sort...However it still does not =/

  10. #9
    Junior Member
    Join Date
    Sep 2010
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Collection.sort problem

    Ah thanks helloworld922! That solved my problem! =)

    Now another question, if I wish to search for a title in the arraylist, is there a simple way to do this?

  11. #10
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: Collection.sort problem

    Well, since you already have Book as Comparable, the List.indexOf(Object o) method might work.

    (Might work, not sure)
    Say you wanted to search for a Book with the title: "Java"
    Since your comparing via the Book Name, you could say:
    //Where List is your List
    int bookIndex = List.indexOf(new Book("Java",0,0,0,new ArrayList<Author>());
    That creates an arbitrary Book Object, where all we care about is the Book Name, and then garbage collects it after we get our Book Index. This will work, as long as the indexOf method compares based on your compareTo method, and as long as your compareTo method ONLY compares the Book Names. If it doesnt, then it won't work.

    Try it and tell me if it works, I'm curious myself.
    Last edited by aussiemcgr; September 21st, 2010 at 10:10 AM. Reason: Wrong Method

  12. #11
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,320
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Collection.sort problem

    Quote Originally Posted by aussiemcgr View Post
    Well, since you already have Book as Comparable, the List.indexOf(Object o) method might work.
    indexOf uses the equals method to retrieve objects from a List. So this will not work unless you override the equals method to enable equality by title. (As stated in the API for List: "More formally, returns the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index. ")

    Now another question, if I wish to search for a title in the arraylist, is there a simple way to do this?
    Iterate over the list and check for string equality.
    for ( int i = 0; i < list.size(); i++ ){
        if ( list.get(i).getTitle().equals(searchTitle) ){
            return list.get(i);
        }
    }

    Alternatively, you could store a Map of the books keyed by title, which would be much faster but a bit more complex to implement

  13. #12
    Junior Member
    Join Date
    Sep 2010
    Posts
    8
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Collection.sort problem

    @copeg - Thanks! that worked like a charm! =)

  14. #13
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Collection.sort problem

    So that Books is a List and that as soon as you add a book to the list the list should sort...However it still does not =/
    You can't simply add a new item and assume it will be put in sorted order into your arraylist. There are two options:

    1. Re-sort your arraylist.
    2. Manually look for where the book needs to be inserted in order to maintain sorted order in your arraylist. This should be simple enough since book already implements comparable, just look for the first spot where the book you're trying to add compared to the book at a given index first becomes positive. If you've reached the end of the list without this being satisfied, you can add it to the end. Otherwise, you need to insert your book into the location index (so the book currently at index would be moved back one).

Similar Threads

  1. bubble sort and selection sort on strings
    By Sir Saula in forum What's Wrong With My Code?
    Replies: 5
    Last Post: July 3rd, 2010, 09:44 AM
  2. bubble sort timer problem
    By JavaNoob82 in forum Algorithms & Recursion
    Replies: 1
    Last Post: March 12th, 2010, 09:22 AM
  3. Java Garbage Collection and destructors
    By riddhik84 in forum Java Theory & Questions
    Replies: 5
    Last Post: October 1st, 2009, 09:06 AM
  4. Garbage Collection?
    By kalees in forum Collections and Generics
    Replies: 6
    Last Post: September 23rd, 2009, 03:07 AM
  5. Help with Sort arrays
    By drk in forum Collections and Generics
    Replies: 5
    Last Post: September 6th, 2009, 02:48 AM

Tags for this Thread