开发者

Java implementing comparator on ArrayList

开发者 https://www.devze.com 2023-01-15 15:14 出处:网络
I\'m quite new to Java so this is probably pretty straight forward question. I want to sort an ArrayList in the class MediaLib based on the natural order of a specified key.

I'm quite new to Java so this is probably pretty straight forward question.

I want to sort an ArrayList in the class MediaLib based on the natural order of a specified key.

I can't work out how to use my comparator (compareTo(MediaInterface, key)) which is in the Media class. Whats the best way to go about this?

package assign1;

import java.util.*;

public class Media implements MediaInterface {

    private Map<String, Object> fields;
    private static int compare;

 public Media(String title, String format) {
     fields = new TreeMap<String, Object>();
     fields.put("title", title);
     fields.put("format", format);
 }


 public Object get(String key) {
  return fields.get(key);
 }


 public void put(String key, Object value) {
  fields.put(key, value);
 }


 public boolean hasKeywords(String[] words, boolean combineWithAND) {
     Collection<Object> values = (Collection<Object>) fields.values();
     int count = 0;
  int size = 0;
  for (String s: words) {
         for (Object o: values) {
                String t = o.toString();
                if (t.indexOf(s) >= 0) {
                    count++;
                    break;
                }
         }
         size++;
  }
  if ((count == 0 && !combineWithAND) || (combineWithAND && (count != size))) {
      return false;
  }
  return true;
 }


 public int compareTo(MediaInterface mi, String key) { //<开发者_运维技巧<<<<<<------calling this!!
  if (mi == null)
   throw new NullPointerException();
  Media m = (Media) mi;
  Comparable mValue = (Comparable) m.get(key);
  Comparable lValue = (Comparable) fields.get(key);
  if ((mValue == null) && (lValue == null)){
      return 0;
  }
  if ((lValue == null)){
            return 1;
        }
  if ((mValue == null)){
            return -1;
        }
  return (lValue).compareTo(mValue);
 }


 @Override
 public int compareTo(MediaInterface mi) {
  if (mi == null)
   throw new NullPointerException();
  Media m = (Media) mi;
  Set<String> lSet = fields.keySet();
  if (compareTo(m, "title") != 0) {
      return compareTo(m, "title");
  }
  if (compareTo(m, "year") != 0) {
            return compareTo(m, "year");
        }
  for (String s: lSet) {
      if (compareTo(m, s) != 0) {
          return compareTo(m, s);
      }
  }
  return 0;
 }


 public boolean equals(Object object) {
  if (object == null)
   return false;
  if (!(object instanceof Media))
   return false;
  Media m = (Media) object;
  if (compareTo(m) != 0) {
      return false;
  }
  return true;
 }
}

    package assign1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;

public class MediaLib implements Searchable {
 private ArrayList<MediaInterface> media;

 public MediaLib() {
  media = new ArrayList<MediaInterface>();
 }


 @Override
 public void add(MediaInterface mi) {
  if (media.isEmpty()) {
      media.add(mi);
  }
  else {
      for (MediaInterface m: media) {
          if (mi.equals(m)) {
              return;
          }
      }
      media.add(mi);
  }
 }


 @Override
 public boolean contains(MediaInterface mi) {
     for (MediaInterface m: media) {
            if (mi.equals(m)) {
                return true;
            }
        }
     return false;
 }


 @Override
 public Collection<MediaInterface> findByKeyword(String[] words, boolean combineWithAND) {
  Collection<MediaInterface> foundList = new ArrayList<MediaInterface>();
     for (MediaInterface mi: media) {
      if (mi.hasKeywords(words, combineWithAND)) {
          foundList.add(mi);
      }
  }
     return foundList;
 }


 @Override
 public Collection<MediaInterface> findByTitle(String str) {
     Collection<MediaInterface> foundList = new ArrayList<MediaInterface>();
        for (MediaInterface mi: media) {
            if ((mi.get("title")).equals(str)) {
                foundList.add(mi);
            }
        }
        return foundList;
 }


 @Override
 public Collection<MediaInterface> getAllWithFormat(String formatName) {
     Collection<MediaInterface> foundList = new ArrayList<MediaInterface>();
        for (MediaInterface mi: media) {
            if ((mi.get("format")).equals(formatName)) {
                foundList.add(mi);
            }
        }
        return foundList;
 }

 public Collection<MediaInterface> getAll() {
     Collection<MediaInterface> fullList = new ArrayList<MediaInterface>();
        for (MediaInterface mi: media) {
            fullList.add(mi);
        }
        return fullList;
 }


 @Override
 public void removeAllWithKeyword(String[] words, boolean combineWithAND) {
     Collection<MediaInterface> foundList = findByKeyword(words, combineWithAND);
     for (MediaInterface mi: foundList) {
         media.remove(mi);
     }
 }


 @Override
 public void removeAllWithFormat(String format) {
     Collection<MediaInterface> foundList = getAllWithFormat(format);
        for (MediaInterface mi: foundList) {
            media.remove(mi);
        }
 }


 @Override
 public void sort() {
     Collections.sort(media);
 }


 @Override
 public void sort(final String fieldName) {  
     Collections.sort(media, new Media.compareTo(MediaInterface, fieldName))  //<<<<<--------Trying to call compareTo()

     }
 }


 public void parse(java.io.BufferedReader br) throws java.io.IOException {
     while(br.readLine()!= null) {
         Media mi = new Media(/n br.readLine(), br.readLine());
         while 

     }
 }
}


You already implement the Comparable interface in your MediaInterface class, this is a generic interface, so you then implement Comparable<MediaInterface> which will then require you to implement a method with the signature

public int compareTo(final MediaInterface other)

This is why your call to Collections.sort(media); compiles

In order to sort by a specific field name, you need to provide an instance of a Comparator, the easiest way to do this will be to create an inner class in your Media class which you can then pass into Collections.sort. For example

public class Media implements MediaInterface {
    public static final class FieldComparator implements Comparator<Media> {
        private final String field;

        public FieldComparator(final String field) {
            this.field = field;
        }

        public int compare(final Media a, final Media b) {
            // implementation to compare a.field to b.field
        }
    }
}

You can then rewrite your second sort method as

@Override
public void sort(final String fieldName) {  
    Collections.sort(media, new Media.FieldComparator(fieldName));
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号