Collection.sort( acollection )

i have
1.)two classes Cd and CompilationCd. the both are subsclass of AbstractCd
2.)AbstractCd class implements Comparale interface.
3.) i have another class called CDCollection that has a map of of CDs where
the key is some given category and the value a list of CDs(both CompilatinCd and Cd)
e.g
< R&B, (ArrayList of  CompilatinCd and Cd ) >
4.) In order for me to sort (ArrayList of  CompilatinCd and Cd ) of my map by the title of my CDs
i implement compareTo() and the call Collections.sort(  (ArrayList of  CompilatinCd and Cd )  );

MY PROBLEM: the (ArrayList of  CompilatinCd and Cd )   is NOT being sort.

What should do intead , See code below:
NOTE: Everything is working fine with this code but the sorting.

================== AbstractCd =============================
public  abstract class AbstractCd
implements Comparable
{
   
    private String title;
    private String musicCompName;
    private String copyRightDate;
    private String category;
    private String type;
    protected int  numOfTracks;
    public static final String EOS = null;
   
    public abstract String getCdInfo();
    private String line ;
   
    /** Creates a new instance of AbstractCd */
    public AbstractCd(String fields[])
    {
        initCd(fields);
    }
   
    public void initCd(String fields[])
    {
        if(fields.length >= 5)
        {
            category = fields[0];
            type = fields[1];
            title = fields[2];
            musicCompName = fields[3];
            copyRightDate = fields[4];
        }

    }
        public boolean equals(Object o)
    {
        if(o == null)
            return false;
        if(o == this)
            return true;
        if(!(o instanceof Cd))
            return false;
        AbstractCd other = (AbstractCd)o;
        return (this.category).equals(other.getCategory()) &&
        (this.musicCompName).equals(other.getName()) &&
        (this.copyRightDate).equals(other.getCopyRight());
    }
   
    /**
     *Compares objects
     *@param: return 1, 0 or -1 to indicate > == or <
     */
    public int compareTo(Object o)
    {
        AbstractCd other = (AbstractCd)o;    
         if(this.musicCompName.compareTo(other.getName()) < 0  ||
        this.title.compareTo(other.getTitle()) < 0 ||
        this.copyRightDate.compareTo(other.getCopyRight()) < 0 )
             return -1;
       
         if(this.musicCompName.compareTo(other.getName()) > 0  ||
             this.title.compareTo(other.getTitle()) < 0 ||
        this.copyRightDate.compareTo(other.getCopyRight()) > 0 )
             return 1;
       
        return 0;
       
    }
   
   public int hashCode()
   {
       int result = 17;
       
       result = 37 * result + category.hashCode();
       result = 37 * result + title.hashCode();
       result = 37 * result + musicCompName.hashCode();
       result = 37 * result + copyRightDate.hashCode();
       
       return result;
    }
   
}
================== Cd =============================

public final class Cd extends AbstractCd

{

    private  int numOfTracks ;

    private String artistName;

    private List tracks = new ArrayList();

    protected final JLabel artistLabel = new JLabel();

    /**
     *constructor
     *
     *@param Creates a new instance of Cd
     */
    public Cd(String fields[], BufferedReader in)
    {
        super(fields);
        initCd(fields,in);
       
    }
   
    /**
     *
     *@param    return artistName
     */
    public String getArtist()
    {
        return artistName;
    }
   
    public int getCdSize()
    {
        return tracks.size();
    }
   

   
   
    /**
     *Compares objects
     *@param: true or false is returned.
     */
    public boolean equals(Object o)
    {
        if(o == null)
            return false;
        if(o == this)
            return true;
        if(!(o instanceof Cd))
            return false;
        Cd other = (Cd)o;
        return super.equals(other) && 
        (this.artistName).equals(other.getArtist());
    }
   
    /**
     *Compares objects
     *@param: return 1, 0 or -1 to indicate > == or <
     */
    public int compareTo(Object o)
    {
         Cd other = (Cd)o;  
         int result = super.compareTo(other);
         if(result != 0)
             return result;
         return this.artistName.compareTo(other.getArtist());
         
    }
   
   public int hashCode()
   {
       int result = 17;
       result = super.hashCode();
       result = 37 * result + artistName.hashCode();
   
       return result;
   }
   
   public void initCd(String fields[], BufferedReader in)
   {
       try
       {
            artistName = fields[ fields.length -1 ];
            super.initCd(fields);
           
            numOfTracks = Integer.parseInt(in.readLine());
            for(int i = 0; i < numOfTracks; i++){
                tracks.add((String)in.readLine());
            }
       }
       catch(IOException e)
       {
            System.err.print("Unexpected IO erro: " + e);
        }
       
   }
   
   public String getCdInfo()
   {
       return super.getTitle() + " -- " + artistName +" \n";
   }
   
}
================== CompilationCd =============================
public final class CompilationCd extends AbstractCd
{
   private int numOfTracks ;
   private Map CompilationTrack = new HashMap();
   public CompilationCd(String fields[], BufferedReader in)
   {  
        super(fields);
        initCd(fields,in);
   }
 
    /*
     *@param: overload toString
     */
    public String toString()
    {
        String s = "" ;
     
        int j = 0;
        for(Iterator i =CompilationTrack.entrySet().iterator(); i.hasNext(); j++)
        {
            Map.Entry e = (Map.Entry)i.next();
           s += j+". "+ e.getKey() + " -- " + (String)e.getValue() +"\n";
        }
        return super.toString() + s;
    }
   
    /**
     *Compares objects
     *a compilation cd is equal to regular cd if they are made by the same
     *company
     *@param: true or false is returned.
     */
    public boolean equals(Object o){
        if(o == null)
            return false;
        if(o == this)
            return true;
        if(!(o instanceof CompilationCd ))
            return false;
       CompilationCd other = (CompilationCd)o;
        return super.equals(other);
   
    }
   
   
    /**
     *Compares objects
     *@param: return 1, 0 or -1 to indicate > == or <
      */
     public int compareTo(Object o)
     {
       CompilationCd other = (CompilationCd)o;  
        int result = super.compareTo(other);
        if(result != 0) return
            result;
        return 0;

    }
   
    public int hashCode()
    {    
       return super.hashCode();
    }  
   

}
=====================CDCollection ( where Cllections.sort is called ======================
public class CDCollection

{
    private Map CDCollections = new HashMap();
    private List CDs = new ArrayList();
    private String category, title,artistName;
    private Cd aCD;
    private CompilationCd aCompCD;
    private CDCollection aCDCollection;    
    private AbstractCd typeOfCd;
    public static final String EOS = null;
    private SortedSet genresOnFile =
    new TreeSet(Arrays.asList(new String[]{"All"}));
   
    /** Dose not do a */
    public CDCollection()
    {
        read();
    }
   
    /*
     *Ask the user for a file name, read the file in
     *the test file name used is "f.txt"
     */
     public void read()
    {
         // String  FileName = JOptionPane.showInputDialog(null,
             //                                         "Enter CDs file:");
        try
        {
            String line;
             BufferedReader infile =
             new BufferedReader( new FileReader
             ("C:/Documents and Settings/Agbeko Komla/.netbeans/3.6/sampledir/a5/f.txt"));
            while( ( line = infile.readLine()) != EOS )
            {
                String fields[] = line.split("\\|");
               
                   String currentCategory = fields[0];
                   String CdType = fields[1];

                if( "0".equals(CdType))
                {
                   typeOfCd = new Cd(fields,infile);
                 genresOnFile.add(typeOfCd.getCategory());
                }

               if( "1".equals( CdType) )
               {
                   typeOfCd = new CompilationCd(fields,infile);
                 genresOnFile.add(typeOfCd.getCategory());
                 }
               
                 if(CDCollections.containsKey( currentCategory ))
                   {
                      ArrayList currentListValue =
                                  (ArrayList)CDCollections.get(currentCategory);
                                  currentListValue.add(typeOfCd);
                  }
                     
                   if( !CDCollections.containsKey(currentCategory) )
                   {
                       List CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );
                   }
                   Collections.sort(CDs);                 <==================== SORTING
                }
               infile.close();
         }
        catch(IOException e)
        {
            System.err.print("Unexpected IO erro: " + e);
        }
    }
}
komlaaaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sciuriwareCommented:
Collections.sort() uses its own comparator.
You should force sorting by:                  Collections.sort(CDs, myComparator);
Easiest is rewriting code like:

                 Collections.sort(CDs, new Comparator()
                 {
                       public int compareTo(Object o)
.............................................................................here comes the code you already wrote .........................
                 });

<*>
0
petmagdyCommented:
the reason is obvoius to fail the sort this is because, u have an ArrayList of both CompilationCd and Cd each overide compareTo(..) and equal(..) that assumes that the incoming object is always from the same Type, which is not in  ur case!
hence u have one of 3 solutions:
1- don't put CompilationCd and Cd in the same array
2- don't overwride compareTo(..) and equal(..)  of the base abstract
3- for example ur compareTo in cd should be like this:

    public int compareTo(Object o)
    {
         if( o instanceof Cd)
         {
           Cd other = (Cd)o;  
           int result = super.compareTo(other);
           if(result != 0)
             return result;
           return this.artistName.compareTo(other.getArtist());
         }
         else
        {
          return super.compareTo(o);
        }
    }

u will do the same in CompilationCd
0
komlaaaAuthor Commented:
Here are the changes u suggested but still .... What is still incorrect?

=============== In AbstractCd compareTo ( ) is now: ==============
  public int compareTo(Object o)
    {
        AbstractCd other = (AbstractCd)o;    
        // if(this.musicCompName.compareTo(other.getName()) < 0  &&
        if( this.title.compareTo(other.getTitle()) < 0 )
       // this.copyRightDate.compareTo(other.getCopyRight()) < 0 )
             return -1;
       
         //if(this.musicCompName.compareTo(other.getName()) > 0  &&
           if( this.title.compareTo(other.getTitle()) > 0 )
        //this.copyRightDate.compareTo(other.getCopyRight()) > 0 )
             return 1;
       
        return 0;
       
    }
  =============== In Cd compareTo ( ) is now: ==============
 public int compareTo(Object o)
    {
        if(o instanceof Cd)
        {
             Cd other = (Cd)o;  
            int result = super.compareTo(other);
            if(result != 0)
              return result;
         return this.artistName.compareTo(other.getArtist());
        }
        else
        {
            return super.compareTo(o);
        }
    }
  =============== In CompilatinCd compareTo ( ) is now: ==============

 public int compareTo(Object o)
     {
         if(o instanceof CompilationCd )
         {
            CompilationCd other = (CompilationCd)o;  
            return super.compareTo(other);
         }
         else
         {
            return super.compareTo(o);
         }
     
    }
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

komlaaaAuthor Commented:
And in CDCollection, as sciuriware suggested,
============Comparator ==========
  Collections.sort
                   (CDs, new Comparator()
                            {
                                public int compare(Object o1, Object o2)
                                {
                                 Cd c1 = (Cd)o1;
                                 CompilationCd c2 = (CompilationCd)o2;
                                if ( ( ((String)c1.getTitle() ).compareTo( (String)c2.getTitle() ) ) < 0 )
                                     return -1;
                                 if( ( (String)c1.getTitle() ).compareTo(  (String)c2.getTitle() ) >0)
                                 {
                                     return 1;
                                 }
                                 return 0;
                                }
                            }
                   );
0
petmagdyCommented:
ur problems is something different in ur code CDS is always empty! this is because:

                   if( !CDCollections.containsKey(currentCategory) )
                   {
                       List CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );
                   }

should be:

                   if( !CDCollections.containsKey(currentCategory) )
                   {
                       CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );
                   }
0
komlaaaAuthor Commented:


I give a try to your suggestion, didn't work, crashes

I think
if( !CDCollections.containsKey(currentCategory) )
                   {
                       List CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );
                   }
is perfect because if there is no such key in map already i want to create
an EMPTY arrayList and then add the first typeOfCd to it.
Notice that
 if(CDCollections.containsKey( currentCategory ))
                   {
                      ArrayList currentListValue =
                                  (ArrayList)CDCollections.get(currentCategory);
                                  currentListValue.add(typeOfCd);
                  }
handle the case where there is already such key, ... i just add to the list of that key.
0
komlaaaAuthor Commented:
Everything works fine for this code except the sorting.
0
petmagdyCommented:
could please test this and post here the results, put before the sort line the following:
Iterator itr = CDs.iterator();
while(itr.hasnext())
{
 Object obj = itr.next();
  System.out.println("Class Type: " + obj.getClass().getName());
}
0
komlaaaAuthor Commented:
============ your code tried here ===================
if( !CDCollections.containsKey(currentCategory) )
                   {
                       List CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );

                       Iterator itr = CDs.iterator();
                        while(itr.hasNext())
                   {
                      Object obj = itr.next();
                    System.out.println("Class Type: " + obj.getClass().getName());
                  }
               }
============= OUTPUT ======================
Class Type: a5.Cd
Class Type: a5.Cd
Class Type: a5.CompilationCd
Class Type: a5.CompilationCd
Class Type: a5.Cd
Class Type: a5.CompilationCd
Class Type: a5.CompilationCd
Class Type: a5.CompilationCd
Class Type: a5.Cd
Class Type: a5.CompilationCd

0
petmagdyCommented:
nooooo!!
 that is what I am saying, i want u to try it like this:

if( !CDCollections.containsKey(currentCategory) )
                   {
                       List CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );

                  }
                    Iterator itr = CDs.iterator();
                        while(itr.hasNext())
                   {
                      Object obj = itr.next();
                    System.out.println("Class Type: " + obj.getClass().getName());
                  }
                   Collections.sort(CDs);                 <==================== SORTING

please try it as i told u
I want u to under understand this, becuase u declared CDs again inside the if condition it u r working on a different instance than the CDs member field
0
petmagdyCommented:
again, what i am trying to tell u the CDs array in:

                   Collections.sort(CDs);                 <==================== SORTING
is never filled in with values!!

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
petmagdyCommented:
to provide more clarification on that in Java the scope of a Variable if defined within brackets "{ }" remains within the brackets like try, if ,while  etc...
hence in ur case u have 2 different variables the List CDs class member varialble and the one defined within ur if condition in:

>>

                   if( !CDCollections.containsKey(currentCategory) )
                   {
                       List CDs = new ArrayList( );
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );
                   }
 
>>

the one in the if condition is filled with items while ur member method used within:

                   Collections.sort(CDs);                 <==================== SORTING
is always empty

did u got what i mean? welling to explain more :)
0
komlaaaAuthor Commented:
> Collections.sort(CDs);                 <==================== SORTING
>is never filled in with values!!
I understand that, i couldn't have any output.

Now i move  :Collections.sort(CDs , Com....);   to:
 catch(IOException e)
        {
            System.err.print("Unexpected IO erro: " + e);
        }
        <===========================after the while loop,
                   Collections.sort(CDs, Comp....);
I couldn't get the typeOfCd sorted by title i am sure it is due to something else.
0
petmagdyCommented:
please try this for me keep the class CDCollection as it is originally but comment one line in ur if condition:

                   if( !CDCollections.containsKey(currentCategory) )
                   {
                  //     List CDs = new ArrayList( ); <----Please comment this line and try
                       CDs.add( typeOfCd );
                       CDCollections.put( currentCategory, CDs );
                   }
0
komlaaaAuthor Commented:
:) I did get the Cd sorted by title!,(when i comment the other line) But they all went to one categoy of CD
I would like to have something like
< <category1> , <List of Cd and CompilationCd> >
< <category2> , <List of Cd and CompilationCd> >
< <category3> , <List of Cd and CompilationCd> >
....
....
0
komlaaaAuthor Commented:
thanks a lot, u bring me to the concept
0
petmagdyCommented:
no I started to understand what u want, then do this:

1- return the commented line (yes this is because a miss understanding, ur problem was not communicated propably)
2- comment the member method <    private List CDs = new ArrayList(); > u don't need it
3- instead of:

    >>               Collections.sort(CDs);                 <==================== SORTING

do this:
      Set keySet = CDCollections.keySet();
     Object[] Keys = keySet.toArray();
     //Sort the keys
     Arrays.sort(keys);
    // now sort the CDCollections ArrayList values
    for(int i=0; i < keys.length ; i++)
   {
     List aCDArray = (List) CDCollections.get(keys[i]);
     Collections.sort(aCDArray);
     // here u can print the Key[i] as the key and aCDArray as the value
   }

0
komlaaaAuthor Commented:
ok
0
petmagdyCommented:
sorry just little correcton
>> 2- comment the member method <    private List CDs = new ArrayList(); > u don't need it
I mean the member field
0
komlaaaAuthor Commented:
... In order for me to be able to sort it the listvalue by title, i have remove the other fields as
indicate below. Do u think this the only way i can achieve this?

=================== compareTo from super class =======================
public int compareTo(Object o)
    {
        AbstractCd other = (AbstractCd)o;    
         if(this.musicCompName.compareTo(other.getName()) < 0  ||  <==== need to be removed
        this.title.compareTo(other.getTitle()) < 0 ||
        this.copyRightDate.compareTo(other.getCopyRight()) < 0 ) <==== need to be removed
             return -1;
       
         if(this.musicCompName.compareTo(other.getName()) > 0  ||<==== need to be removed
             this.title.compareTo(other.getTitle()) < 0 ||
        this.copyRightDate.compareTo(other.getCopyRight()) > 0 ) <==== need to be removed
             return 1;
       
        return 0;
       
    }
0
petmagdyCommented:
yes just use title, but at the end it depends on ur requirments
0
komlaaaAuthor Commented:
I actually not supposed to change anything in AbstractCd class
0
petmagdyCommented:
u know better it is ur code and logic at the end and u who understand the requirments of ur application
0
komlaaaAuthor Commented:
Thanks man!!
0
petmagdyCommented:
welcome :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.