aspose file tools*
The moose likes Java in General and the fly likes Sorting an ArrayList is giving me fits Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Sorting an ArrayList is giving me fits" Watch "Sorting an ArrayList is giving me fits" New topic
Author

Sorting an ArrayList is giving me fits

Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
This is my first post on this board. I am a java beginner, however, I have a graduate level class right now that requires a functional knowledge system that is written in java. Halfway through the class we started looking at Java and it's way more complicated than I expected. I am no stranger to programming (Basic, Pascal, Fortran, Matlab, VBA (teensy bit)), although I am no expert in any of them. So, this project is due in just a couple of weeks and I've made some progress, but one function has eluded me. Sorting an arraylist of objects on a certain attribute.

I was able to read the objects in from an Excel file (with much help), and create the arraylists that I need. I figured out how to access the individual attributes of each object in the list and do calculations on them. But, I can't go any further until I can sort these lists. I have been reading java tips for hours, so I know that I need to use Collections.sort with a comparator. But, after trying various methods and copying code directly from the sun java site, all I get are various errors that don't allow me to run it. I have tried using generics (even though I don't really understand them), but all of those attempts result in errors I cannot resolve. It's difficult to post the exact error because everytime I change a piece of syntax to correct one error, the error shifts to something else.

Here is what I have:

public class Player implements Comparable<Player> {
public static Comparator ByName = new NameComparator();
public static Comparator ByFanPointTotal = new FanPointComparator();
public String toString() {
return "name = " + getName() + ", position = " + getPosition()+", FanTeam = "+getFanTeam()
+ ", FanPointTotal = " + getFanPointTotal()+", Diff = "+getDiff()+", DiffofDiff = "+getDiffOfDiff();
}


The error here is "The type Player must implement the inherited abstract method Comparable<Player>.compareTo
(Player)" But when I go to put this compareTo method in, it wants it to be abstract, and then it wants the class to be abstract. But, I have multiple instantiations of Player, so it can't be abstract. So, I don't know what to do with that.

class NameComparator implements Comparator{
public int compare(Player p1, Player p2){
// parameter are of type Object, so we have to downcast it to Employee objects
String p1Name = ( (Player) p1 ).getName();
String p2Name = ( (Player) p2 ).getName();
// uses compareTo method of String class to compare names of the employee
return p1Name.compareTo(p2Name);
}
}

No errors on this.

Then in my executable class that contains the arraylist "availplayers"

public ArrayList<Player> availplayers = new ArrayList<Player>();
// i read in my excel data and create the arraylist
Collections.sort(availplayers, NameComparator);


The error here is "NameComparator cannot be resolved". I think this is the minimum error configuration I've been able to come up with. I know there is something going on with generics, but when I've removed all of that, it still didn't work.

Please help. I just need some guidance in plain english for a beginner who is off to a hurried start and needs to have this program working in 2 weeks!

They have us using Eclipse, so I have the tools. I just don't have the knowledge.

Thanks
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

Welcome to the ranch !

If you want to use separate Comparators, you don't need to make the Player Comparable. This solves your compiling error !
And also, in NameComparator, you don't need to cast a Player to Player. It's already a Player ! For example, String p1Name = ( (Player) p1 ).getName(); becomes String p1Name = p1.getName();
The NameComparator compares Players, so it should look like :



The error here is "NameComparator cannot be resolved".

Use Collections.sort(availplayers, Player.ByName); instead. (By the way, Instance variables are better looking with a starting lower case character.)


[My Blog]
All roads lead to JavaRanch
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
Thanks for the lightning fast reply. I made the changes you suggested, but now I get this...

Collections.sort(availplayers, Player.ByName);

Errors:
- The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the
arguments (ArrayList<Player>, Comparator)
- Player cannot be resolved
- The type NameComparator is not generic; it cannot be parameterized with arguments <? super
Player>

So, here's the generics stuff cropping up. I have no idea what <? super T> is.
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

Did you notice that I have corrected my post ? You have to make NameComparator implement Comparator<Player>.
D. Ogranos
Ranch Hand

Joined: Feb 02, 2009
Posts: 214
Jason Guyton wrote:Thanks for the lightning fast reply. I made the changes you suggested, but now I get this...

Collections.sort(availplayers, Player.ByName);

Errors:
- The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the
arguments (ArrayList<Player>, Comparator)
- Player cannot be resolved
- The type NameComparator is not generic; it cannot be parameterized with arguments <? super
Player>

So, here's the generics stuff cropping up. I have no idea what <? super T> is.


You have a list of type "ArrayList<Player>", to use Collections.sort you then need a comparator of type "Comparator<Player>". Change your definition of NameComparator and it should work. I'm actually surprised you didn't get a compile error on that before, because you just declare it as Comparator but then write a method "compare(Player a, Player b)".

Oops, someone was faster ;) dang hehe
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

Here is a sample on how things work :
Player class (actually, you may not need to keep a static instance of each Comparator)

NameComparator class

Main class


Teh NameComparator is a Comparator which can compare Player. You can use it with the Collections.sort method to sort any Player collection. You would have made Player a Comparable class if you wanted to use Collections.sort(playerList) instead.
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
When I do

public class NameComparator implements Comparator<Player>{

I get
Error: The type Comparator is not generic; it cannot be parameterized with arguments <Player>
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

Strange. Are you using java.util.Comparator ? Make sure you're not using one of your own class which has the same name. To check this, try to use "implements java.util.Comparator<Player>" instead.
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
Now I have this:

public class Player {

public static Comparator ByName = new NameComparator();
public static Comparator ByFanPointTotal = new FanPointComparator();


Error: Type mismatch: cannot convert from NameComparator to Comparator

public class NameComparator implements Comparator<Player>{
public int compare(Player p1, Player p2){
// parameter are of type Object, so we have to downcast it to Employee objects
String p1Name = p1.getName();
String p2Name = p2.getName();
// uses compareTo method of String class to compare names of the employee
return p1Name.compareTo(p2Name);
}
}


Error: The type Comparator is not generic; it cannot be parameterized with arguments <Player>

Collections.sort(availplayers, new NameComparator());

Error: The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the
arguments (ArrayList<Player>, NameComparator)

I have been chasing these errors around for several days unable to find the right combination to make it happy.
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

You have to tell that the comparator you are using is a comparator of Players. So :

Or as I said previously, you could get read of those static comparators if you really don't need them.
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
Christophe Verré wrote:Strange. Are you using java.util.Comparator ? Make sure you're not using one of your own class which has the same name. To check this, try to use "implements java.util.Comparator<Player>" instead.


Oh, I did have a class named Comparator in the same package while I was messing around with different ways to make it work. I just deleted it. I can see why that would cause a problem. GREAT, PROBLEM SOLVED!??

Sadly no. The errors are still there.
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
Jason Guyton wrote:
Christophe Verré wrote:Strange. Are you using java.util.Comparator ? Make sure you're not using one of your own class which has the same name. To check this, try to use "implements java.util.Comparator<Player>" instead.


Oh, I did have a class named Comparator in the same package while I was messing around with different ways to make it work. I just deleted it. I can see why that would cause a problem. GREAT, PROBLEM SOLVED!??

Sadly no. The errors are still there.


YOU, SIR, ARE A LIFE SAVER!!!

I cannot thank you enough. HOLY SH$% I can't believe it. I actually had the code correct at some point, but I had a class hanging around in the package called Comparator. Duh. I guess just deleting the class didn't completely wipe the conflict. Your java.util suggestion did the trick. WOW! I'm so glad I posted here. I kept thinking that I just needed to ask a Java genius. Thanks guys. I doubt this will be the last you hear from me. I still have a lot of work to do.
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

Good to hear your problems are solved.
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
OK, that helped my sort issue. Now I have different issue because I don't know how to use eclipse very well. I had a package that contained all of these classes for trying different stuff. I went to clean them up, so I deleted the ones I wasn't using. I also saw something weird in the UML class diagram. So, I deleted that and had Eclipse regenerate the class diagram from the code.

My problem: The class that has main in it won't Run as .. Java Application anymore. What happened? It all seems like the same code.
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14688
    
  16

The class that has main in it won't Run as .. Java Application anymore. What happened? It all seems like the same code.

You mean that when you right-click on the main class and select Run/Java Application, your app doesn't start ? Or the menu does not even appear ?
Jason Guyton
Ranch Hand

Joined: Apr 15, 2010
Posts: 40
Christophe Verré wrote:
The class that has main in it won't Run as .. Java Application anymore. What happened? It all seems like the same code.

You mean that when you right-click on the main class and select Run/Java Application, your app doesn't start ? Or the menu does not even appear ?


I can run it, and it runs great now thanks to you. But when I right click it, I only get Run as an option. Before I cleaned things up (screwed something up), Run as Java Application was the only option.

It's just a different behavior, and I don't know if that has messed something up.

On a side note, I just created a class to do a whole pile of calcs on certain arraylists (utilizing my newfound sorting ability) and it seems I figured it out on my own! I think it worked!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Sorting an ArrayList is giving me fits