通过对象的Arraylist排序(歌曲)

时间:2015-03-30 00:50:55

标签: java sorting arraylist filtering

所以基本上,这是一个项目,我们得到一个文本文件,其中包含一长串歌曲。使用此文件,我们应该制作Song对象,并能够按艺术家,等级,年份和标题进行排序和过滤。到目前为止,我的大部分工作都是如此。我唯一需要帮助的是分类。过滤方法似乎有效,但排序不起作用(过滤和排序方法在SongCollection类中)。我们应该在其中一种排序方法中使用插入排序,但它似乎不起作用。

Input Text File

客户类:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class GazillionSongs {
    public static void main(String[] args){
        try {
            //Prompt user to enter a file
            System.out.println("This will filter and sort songs.");
            Scanner input = new Scanner(System.in);
            //Stores file in arraylist
            Scanner f = new Scanner(new File("agazillionsongs.txt"));
            //makes array of songs
            ArrayList<Song> list = new ArrayList<Song>();
            //songcollection object
            SongCollection songs = new SongCollection(list);
            //stores songs in arraylist
            while (f.hasNextLine()) {
                Song song = new Song();
                song.parse(f.nextLine());
                list.add(song); 
            }
            //Filters
            System.out.println("Choose a filter. Year, rank, artist, or title?");
            String userInput = input.nextLine();
            //filters By year
            if (userInput.equals("year")){
                System.out.println("Enter a year or range:");
                String year = input.nextLine();
                songs.filterYear(Range.parse(year));
                songs.print();
                //filters by rank   
            } else if(userInput.equals("rank")) {
                System.out.println("Enter a rank or range:");
                String rank = input.nextLine();
                songs.filterRank(Range.parse(rank));
                songs.print();
                //filters by artist 
            } else if(userInput.equals("artist")) {
                System.out.println("Enter an artist");
                String artist = input.nextLine();
                songs.filterArtist(artist);
                songs.print();
                //filters by title  
            } else if(userInput.equals("title")) {
                System.out.println("Enter a title");
                String title = input.nextLine();
                songs.filterTitle(title);
                songs.print();
            } else if(userInput.equals("year and rank")) {
                System.out.println("Enter a year and rank");
                String year = input.next();
                String and = input.next();
                String rank = input.next();
                songs.filterYear(Range.parse(year));
                songs.filterRank(Range.parse(rank));
                songs.print();
            } else if(userInput.equals("artist and title")) {
                System.out.println("Enter artist and title");
                String artist = input.next();
                String and = input.next();
                String title = input.next();
                songs.filterArtist(artist);
                songs.filterTitle(title);
                songs.print();
            } else if(userInput.equals("year and title")) {
                System.out.println("Enter year and title");
                String year = input.next();
                String and = input.next();
                String title = input.next();
                songs.filterYear(Range.parse(year));
                songs.filterTitle(title);
                songs.print();
            } else if(userInput.equals("year and artist")) {
                System.out.println("Enter year and artist");
                String year = input.next();
                String and = input.next();
                String artist = input.next();
                songs.filterYear(Range.parse(year));
                songs.filterArtist(artist);
                songs.print();
            }
            //sorting
            System.out.println("Sort by what?");
            String sortInput = input.next();
            if(sortInput.equals("year")) {
                songs.sortY();
                songs.print();
            } else if (sortInput.equals("rank")) {
                songs.sortR();
                songs.print();
            } else if (sortInput.equals("artist")) {
                songs.sortA();
                songs.print();
            } else if (sortInput.equals("title")) {
                songs.sortT();
                songs.print();
            }
            //file not found
        } catch (FileNotFoundException e) { 
            System.out.println("File not found"); 
        }
    }
}

歌曲课程:

import java.util.StringTokenizer;

public class Song {
    //fields
    public int year;
    public int rank;
    public String artist;
    public String title;
    //constructor
    public Song(int y, int r, String a, String t) {
        year = y;
        rank = r;
        artist = a;
        title = t;
    }
    public Song() {
        // TODO Auto-generated constructor stub
    }
    //parsing
    public Song parse(String s){
        //tokenizer
        StringTokenizer parse = new StringTokenizer(s, "\t");
        //year
        String yr = parse.nextToken();
        year = Integer.parseInt(yr);
        //rank
        String rk = parse.nextToken();
        rank = Integer.parseInt(rk);
        //artist
        artist = parse.nextToken();
        //title
        title = parse.nextToken();
        //song object
        Song song = new Song(year, rank, artist, title);
        return song;
    }
    //getters
    public int getYear(){
        return year;
    }
    public int getRank(){
        return rank;
    }
    public String getArtist(){
        return artist;
    }
    public String getTitle(){
        return title;
    }
    //tostring method
    public String toString(){
        return String.format(year + " " + rank + " " + artist + " - " + title + "\n");
    }
}

SongCollection类:

import java.util.ArrayList;
import java.util.Collections;

public class SongCollection {
    //arraylist
    public ArrayList<Song> list;
    //constructor
    public SongCollection(ArrayList<Song> songs) {
        list = songs;
    }
    //filters by year
    public void filterYear(Range r) {
        for (int i = list.size() - 1; i >= 0; i--) {
            if (!r.contains(list.get(i).getYear())) {
                list.remove(i);
            }
        }
    }
    //filters by rank
    public void filterRank(Range r) {
        for (int i = list.size() - 1; i >= 0; i--) {
            if (!r.contains(list.get(i).getRank())) {
                list.remove(i);
            }
        }
    }
    //filters by artist
    public void filterArtist(String s) {
        for (int i = list.size() - 1; i >= 0; i--) {
            if (!list.get(i).getArtist().contains(s)) {
                list.remove(i);
            }
        }
    }
    //filters by title
    public void filterTitle(String s) {
        for (int i = list.size() - 1; i >= 0; i--) {
            if (!list.get(i).getTitle().contains(s)) {
                list.remove(i);
            }
        }
    }
    //sorts by year
    public void sortYear(Song[] song){
        int in, out;

        for (out = 1; out < song.length; out++) {
            Song temp = song[out];
            in = out;

            while (in > 0 && song[in - 1].getYear() > 0) {
                song[in] = song[in - 1];
                --in;
            }
            song[in] = temp;
        }
    }
    //sorts by rank
    public void sortRank(Song[] song) {
        //insertion sort
        int in, out;

        for (out = 1; out < song.length; out++) {
            Song temp = song[out];
            in = out;

            while (in > 0 && song[in - 1].getRank() > 0) {
                song[in] = song[in - 1];
                --in;
            }
            song[in] = temp;
        }
    }
    //sorts by artist
    public void sortArtist(Song[] song) {
        //insertion sort
        int in, out;

        for (out = 1; out < song.length; out++) {
            Song temp = song[out];
            in = out;

            while (in > 0 && song[in - 1].getArtist().compareTo(temp.getArtist()) > 0) {
                song[in] = song[in - 1];
                --in;
            }
            song[in] = temp;
        }
    }
    //sort by title
    public void sortTitle(Song[] song) {
        //insertion sort
        int in, out;

        for (out = 1; out < song.length; out++) {
            Song temp = song[out];
            in = out;

            while (in > 0 && song[in - 1].getTitle().compareTo(temp.getTitle()) > 0) {
                song[in] = song[in - 1];
                --in;
            }
            song[in] = temp;
        }
    }
    // prints the songs
    public void print() {
        for (int i = 0; i < list.size(); i++) {
            Song song = list.get(i);
            System.out.print(song.toString());
        }
    }
    public void sortY() {
        Song[] arr = list.toArray(new Song[list.size()]);
        sortYear(arr);
    }
    public void sortR() {
        Song[] arr = list.toArray(new Song[list.size()]);
        sortRank(arr);
    }
    public void sortA() {
        Song[] arr = list.toArray(new Song[list.size()]);
        sortArtist(arr);
    }
    public void sortT() {
        Song[] arr = list.toArray(new Song[list.size()]);
        sortTitle(arr);
    }
}

范围类:

import java.util.StringTokenizer;

public class Range {
    public static int min;
    public static int max;
    public static String str;

    public Range(String s){
        str = s;
    }
    public static Range parse(String s){
        //range
        if (s.contains("-")){
            StringTokenizer parse = new StringTokenizer(s, "-");
            String strMin = parse.nextToken();
            min = Integer.parseInt(strMin);
            String strMax = parse.nextToken();
            max = Integer.parseInt(strMax);

        }else{
            min = Integer.parseInt(s);
            max = min;
        }
        Range rangeObj = new Range(str);
        return rangeObj;
    }
    public boolean contains(int n){
        if (min <= n && n <= max){
            return true;
        }
        return false;
    }
    public int getMin(){
        return min;
    }
    public int getMax(){
        return max;
    }
}

2 个答案:

答案 0 :(得分:0)

我认为sort方法应该看起来像这样(只是sortYear()的一个例子,其他的应该遵循相同的模式。但是,我想对于不同的排序标准重用排序算法是有意义的。 ..

public void sortYear(Song[] song){
        int in, out;

        for (out = 1; out < song.length; out++) {
            Song temp = song[out];
            in = out;

            while (in > 0 && song[in - 1].getYear() > temp.getYear() ) {
                song[in] = song[in - 1];
                --in;
            }
            song[in] = temp;
        }
    }

答案 1 :(得分:0)

根据我的意见,你不应该改变你的收藏。它应该包含所有元素。但您应该能够根据需要过滤或订购。 我建议使用google集合guava库https://code.google.com/p/guava-libraries/

你的课堂歌曲可以更多

public final class Song {
  public final String title;
  public final String artist;
  public final int year;
  public final int rank;

  public Song(final String title, final String artist, final int year, final int rank) {
    this.year = year;
    this.rank = rank;
    this.artist = artist;
    this.title = title;
  }

  // With Integer you have the function CompareTo so, you can use Integer instead of int
  public final Integer getYear() {
    return year;
  }

  public final Integer getRank() {
    return rank;
  }

  public final String getArtist() {
    return artist;
  }

  public final String getTitle() {
    return title;
  }

  public final String toString() {
    return String.format(year + " " + rank + " " + artist + " - " + title + "\n");
  }
}

您的排序功能可能如下所示:可以将解析移动到dedecated类以分离关注点。

public List<Song> sortByYear() {
    Collections.sort(songs, new Comparator<Song>() {
        public int compare(final Song first, final Song second) {
            return first.getYear().compareTo(second.getYear());
        }
    });
    return songs;
}

过滤你也可以像这样使用番石榴:

public Collection<Song> filterYear(final Range range) {
    return Collections2.filter(songs, new Predicate<Song>() {
        public boolean apply(final Song song) {
            return range.contains(song.getYear());
        }
    });
}

这里是SongCollection类的一个例子:

import com.google.common.base.Predicate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;

import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.sort;
import static java.util.Collections.unmodifiableCollection;

public class SongCollection {
  public final ArrayList<Song> songs;

  public SongCollection(final ArrayList<Song> songs) {
      this.songs = newArrayList(songs);
  }

  public Collection<Song> filterYear(final Range range) {
      return unmodifiableCollection(filter(songs, new Predicate<Song>() {
        public boolean apply(final Song song) {
            return range.contains(song.getYear());
        }
      }));
  }

  public Collection<Song> filterRank(final Range range) {
    return unmodifiableCollection(filter(songs, new Predicate<Song>() {
        public boolean apply(final Song song) {
            return range.contains(song.getRank());
        }
    }));
  }

  public Collection<Song> filterArtist(final String value) {
    return unmodifiableCollection(filter(songs, new Predicate<Song>() {
        @Override
        public boolean apply(Song song) {
            return song.getArtist().contains(value);
        }
    }));
   }

   public Collection<Song> filterTitle(final String title) {
    return unmodifiableCollection(filter(songs, new Predicate<Song>() {
        public boolean apply(Song song) {
            return song.getTitle().equals(title);
        }
    }));
  }

  public Collection<Song> sortByYear() {
    sort(songs, new Comparator<Song>() {
        public int compare(final Song first, final Song second) {
            return first.getYear().compareTo(second.getYear());
        }
    });
    return unmodifiableCollection(songs);
  }

  public void sortByRank() {
   ...
  }

  public void sortArtist() {
   ...
  }

  public void sortByTitle() {
    ...
  }

  // prints the songs
  public void print() {
    for (final Song song : songs) {
        System.out.print(song.toString());
    }
  }
}