dimanche 29 mars 2015

Sorting Through An Arraylist of Objects (Songs)



So basically, this is a project where we are given a text file that contains a long list of songs. Using this file, we are supposed to make Song objects and be able to sort by and filter by artist, rank, year, and title. I have most of it working so far. The only thing I need help on is the sorting. The filtering methods seem to be working, but sorting does not (the filtering and sorting methods are in the SongCollection class). We are supposed to use insertion sort in one of the sorting methods, but it does not seem to be working.


Input Text File


Client Class:



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");
}
}
}


Song Class:



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 Class:



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);
}
}


Range Class:



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;
}
}



Aucun commentaire:

Enregistrer un commentaire