ArrayList的打印输出到文件? [英] Printing arraylist into output file?

查看:133
本文介绍了ArrayList的打印输出到文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面跟进问题:的Java:ArrayList的打印输出到文件

由于某些原因,它需要的时间的ArrayList数额特别巨大要打印输出文件,通常是20-30分钟。然而,这仅与某种方法或 filterTitle filterArtist 方法(methods这种担心串输入)发生。
当我运行 filterRank filterYear ,它运行完全正常。

当我从过滤方法打印 song2的ArrayList 直接打印在唯一的事情就是 [] ,这意味着的ArrayList 是空的,但它不应该?和 filterRank filterYear 方法不管这仍然工作。
不知怎的,我认为这是相关的,虽然。

输入文件可以在这里找到:<一href=\"http://staff.rentonschools.us/hhs/ap-comp-science/projects/download/agazillionsongs.txt?id=223098\" rel=\"nofollow\">http://staff.rentonschools.us/hhs/ap-comp-science/projects/download/agazillionsongs.txt?id=223098

例如排序方法:

 公共无效sortYear(){
   Collections.sort(songs2,SongComparator.byYear()); //现在我们有一个排序列表
   的System.out.println(songs2);
}

例滤波方法(串)

 公共无效filterArtist(String s)将{
   INT N = 0;
   如果(N == 0){
      的System.out.println(程序正在处理。);
      Ñ​​++;
      对于(宋松1:songs2){
         如果((!(((song1.artist)。载(S))))){
            itemsToRemove.add(松1);
         }
      }
      songs2.removeAll(itemsToRemove);
      itemsToRemove.clear();
   }
   的System.out.println(songs2);
}

例过滤法(整数)

 公共无效filterRank(范围R){
   INT N = 0;
   如果(N == 0){
      的System.out.println(程序正在处理。);
      Ñ​​++;
      对于(宋松1:songs2){
         如果(song1.rank&GT;(r.getMax())||(song1.rank)≤(r.getMin())){
            itemsToRemove.add(松1);
         }
      }
      songs2.removeAll(itemsToRemove);
      itemsToRemove.clear();
   }
   的System.out.println(songs2);
}

code在打印/输出文件的主类

 而(input.hasNextLine()){
   INT N = 0;
   SongCollection收集=新SongCollection(听歌);
   字符串的inputType = input.nextLine();
   字符串delims =[];
   的String []标记= inputType.split(delims);
   的for(int i = 0; I&LT; tokens.length;我++){
      N = 0;
      如果(N == 0){
         如果((令牌[I])包含(年)){
            collection.filterYear(Range.parse(令牌[I]));
            N = 1;
         } //年循环结束
         如果((令牌[I])包含(等级)){
            collection.filterRank(Range.parse(令牌[I]));
            N = 1;
         } //排名结束
         如果((令牌[I])包含(艺术家)){
            collection.filterArtist(令牌[I]);
            N = 1;
         } //艺术家结束
         如果((令牌[I])包含(称号:)){
            collection.filterTitle(令牌[I]);
            N = 1;
         } //标题的结束
         如果((令牌[I])包含(排序)){
               如果((令牌[I])。包含(标题)){
                  collection.sortTitle();
                  N = 1;
               } //排序题结束
               如果((令牌[I])。包含(艺术家)){
                  collection.sortArtist();
                  N = 1;
               } //那种艺术家的结束
               如果((令牌[I])。包含(等级)){
                  collection.sortRank();
                  N = 1;
               } //类级别的结束
               如果((令牌[I])。包含(年)){
                  collection.sortYear();
                  N = 1;
               } //排序年底
         } //排序结束
      } // for循环结束   } // input.hasNextline循环结束
   最终的PrintStream控制台= System.out的; //保存原来的System.out
   文件OUTPUTFILE =新的文件(output.txt的); //输出文件
   PrintStream的出=新的PrintStream(新的FileOutputStream(OUTPUTFILE)); //新的FileOutputStream
   System.setOut(出); //改变,其中的数据将被打印
   的System.out.println(collection.toString());   System.setOut(控制台); //改变输出打印回安慰
   扫描仪outputFileScanner =新的扫描仪(OUTPUTFILE); //从文件输入数据
   而((outputFileScanner.hasNextLine())){//而文件仍然有数据
      的System.out.println(outputFileScanner.nextLine()); //打印
   }
   outputFileScanner.close();
   out.close();
}

全部code编译:

 进口java.io. *;
   进口的java.io.File;
   进口java.io.FileNotFoundException;
   进口的java.util。*;
   进口了java.util.Comparator;
   进口java.util.Scanner中;
   进口java.util.StringTokenizer的;公共类GazillionSongs {
   公共静态无效的主要(字串[] args)抛出FileNotFoundException异常,IOException异常{
      的System.out.println(欢迎到Java歌集!); //问候用户
      System.out的
      .println(这个项目排序和过滤大型数据库的流行歌曲。); //解释程序的目的
      System.out的
      .println(这个程序是能够过滤和排序的一年,艺术家,衔。);
      System.out的
      .println(请输入包含要进行过滤或排序数据库中的文件(即,alistofsongs.txt)。); //示例文件= agazillionsongs.txt
      扫描仪的FileInput =新的扫描仪(System.in); //扫描仪,它接受的文件名
      字符串文件名= fileInput.nextLine();      文件f =新的文件(文件名); //创建一个从输入文件
      / *文件位置错误检查* /
      扫描仪fileScanner =新的扫描仪(F); //从文件输入数据      ArrayList的&LT;宋&GT;歌曲=新的ArrayList&LT;宋&GT;();
      而((fileScanner.hasNextLine())){
         songs.add(Song.parse(fileScanner.nextLine()));
      }      System.out的
      .println(请选择哪些命令你想使用的程序。);
      System.out的
      .println(请格式化您的命令,如下面的例子:一年:其中,一年(S)GT;排名:&LT;秩(S)GT;艺术家:其中,艺术家&GT;标题:LT;标题&GT; sortBy:其中,场&GT ;);
      的System.out.println();
      的System.out.println(你可以挑任意数量的您想要的命令。);
      System.out的
      .println(多年来有地位,你可以选择一个年份范围或行列。);
      System.out的
      .println(对于艺术家和标题,您可以输入部分名称或标题。);
      的System.out.println(即,年份:1983年排名:1);
      扫描仪输入=新的扫描仪(System.in);      而(input.hasNextLine()){
         INT N = 0;
         SongCollection收集=新SongCollection(听歌);
         字符串的inputType = input.nextLine();
         字符串delims =[];
         的String []标记= inputType.split(delims);
         的for(int i = 0; I&LT; tokens.length;我++){
            N = 0;
            如果(N == 0){
               如果((令牌[I])包含(年)){
                  collection.filterYear(Range.parse(令牌[I]));
                  N = 1;
               } //年循环结束
               如果((令牌[I])包含(等级)){
                  collection.filterRank(Range.parse(令牌[I]));
                  N = 1;
               } //排名结束
               如果((令牌[I])包含(艺术家)){
                  collection.filterArtist(令牌[I]);
                  N = 1;
               } //艺术家结束
               如果((令牌[I])包含(称号:)){
                  collection.filterTitle(令牌[I]);
                  N = 1;
               } //标题的结束
               如果((令牌[I])包含(排序)){
                     如果((令牌[I])。包含(标题)){
                        collection.sortTitle();
                        N = 1;
                     } //排序题结束
                     如果((令牌[I])。包含(艺术家)){
                        collection.sortArtist();
                        N = 1;
                     } //那种艺术家的结束
                     如果((令牌[I])。包含(等级)){
                        collection.sortRank();
                        N = 1;
                     } //类级别的结束
                     如果((令牌[I])。包含(年)){
                        collection.sortYear();
                        N = 1;
                     } //排序年底
               } //排序结束
            } // for循环结束         } // input.hasNextline循环结束
         最终的PrintStream控制台= System.out的; //保存原来的System.out
         文件OUTPUTFILE =新的文件(output.txt的); //输出文件
         PrintStream的出=新的PrintStream(新的FileOutputStream(OUTPUTFILE)); //新的FileOutputStream
         System.setOut(出); //改变,其中的数据将被打印
         的System.out.println(collection.toString());         System.setOut(控制台); //改变输出打印回安慰
         扫描仪outputFileScanner =新的扫描仪(OUTPUTFILE); //从文件输入数据
         而((outputFileScanner.hasNextLine())){//而文件仍然有数据
            的System.out.println(outputFileScanner.nextLine()); //打印
         }
         outputFileScanner.close();
         out.close();
      }
   } //主结束
} //类的结束宋级{
   公共枚举令{年份,等级,标题,艺术家}
   公众诠释年;
   公众诠释排名;
   公共字符串的艺术家;
   公共字符串称号;   公共静态解析歌(String s)将{
      Song实例=新曲();
      StringTokenizer的标记生成器=新的StringTokenizer(S,\\ t的);
      instance.year =的Integer.parseInt(tokenizer.nextToken());
      instance.rank =的Integer.parseInt(tokenizer.nextToken());
      instance.artist =(tokenizer.nextToken());
      instance.title =(tokenizer.nextToken());
      返回实例;
   }   公众诠释了getYear(){
      返回年;
   }   公众诠释getRank(){
      返回等级;
   }   公共字符串getArtist(){
      返回的艺术家;
   }   公共字符串的getTitle(){
      返回称号;   }   公共字符串的toString(){
      字符串输出=\\ n \\ nYear =+一年+\\ nRank =+等级+\\ nArtist =
            +艺术家+\\ n标题=+称号;
      返回输出;
   }}
Range类{
   私人诠释分钟;
   私人诠释最大值;   公开范围(){
      的System.out.println(请稍等。);
   }   公共静态解析范围(String s)将{
      例如范围=新范围(); //实例在这里创建这样的对象
                              //变量可能被访问
      字符串字段; //字符串包含用户输入删除的部分
      StringTokenizer的标记者=新的StringTokenizer(S, - );
      StringTokenizer的tokenizer2 =新的StringTokenizer(S,:); //用于分离字段:从
                                                   //字符串的另一部分
      如果(s.contains(:)){//这将删除字段:用户输入,所以
                        //它不与解析干扰
         字段=(tokenizer2.nextToken());
         S = s.replace(字段,);
         S = s.replace(:,);
      }
      如果(s.contains( - )){
         instance.min =的Integer.parseInt(tokenizer.nextToken());
         instance.max =的Integer.parseInt(tokenizer.nextToken());      }否则如果((s.contains( - ))){
         {
            instance.min =的Integer.parseInt(S);
            instance.max =的Integer.parseInt(S);
         }
      }
      的System.out.println(范围最大值=+ instance.max);
      的System.out.println(范围最小=+ instance.min);
      返回实例;
   }   公共布尔为contains(int n)的{
      如果(N GT; min的放大器;&放大器; N&下;最大){//如果号码被包含在范围内,方法返回true。
         返回true;
      }否则如果(N ==分钟和放大器;&安培; N ==最大){
         返回true;
      }其他{
         返回false;
      }
   }   公众诠释getMin(){
      返回分钟;
   }   公众诠释GetMax的(){
      返回最大值;
   }
}
类SongCollection {
   ArrayList的&LT;宋&GT; songs2;
   ArrayList的&LT;宋&GT; itemsToRemove =新的ArrayList&LT;宋&GT;(); //第二个系列
                                             //为项目
                                             // 去掉
   公共SongCollection(ArrayList的&LT;宋&GT;歌曲){//构造SongCollection
      的System.out.println(测试);
      this.songs2 =歌曲;
      }
   公共无效filterYear(范围R){
      INT N = 0;
      如果(N == 0){
         的System.out.println(程序正在处理。);
         Ñ​​++;
         对于(宋松1:songs2){
            如果(song1.year&GT;(r.getMax())||(song1.year)≤(r.getMin())){
               itemsToRemove.add(松1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      的System.out.println(songs2);
   }   公共无效filterRank(范围R){
      INT N = 0;
      如果(N == 0){
         的System.out.println(程序正在处理。);
         Ñ​​++;
         对于(宋松1:songs2){
            如果(song1.rank&GT;(r.getMax())||(song1.rank)≤(r.getMin())){
               itemsToRemove.add(松1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      的System.out.println(songs2);
   }   公共无效filterArtist(String s)将{
      INT N = 0;
      如果(N == 0){
         的System.out.println(程序正在处理。);
         Ñ​​++;
         对于(宋松1:songs2){
            如果((!(((song1.artist)。载(S))))){
               itemsToRemove.add(松1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      的System.out.println(songs2);
   }   公共无效filterTitle(String s)将{
      INT N = 0;
      如果(N == 0){
         的System.out.println(程序正在处理。);
         Ñ​​++;
         对于(宋松1:songs2){
            如果((!(((song1.title)。载(S))))){
            itemsToRemove.add(松1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      的System.out.println(songs2);
   }   公共无效sortTitle(){
        Collections.sort(songs2,SongComparator.byTitle()); //现在我们有一个排序列表
        的System.out.println(songs2);
      }
   公共无效sortRank(){
        Collections.sort(songs2,SongComparator.byRank()); //现在我们有一个排序列表
        的System.out.println(songs2);
      }
   公共无效sortArtist(){
        Collections.sort(songs2,SongComparator.byArtist()); //现在我们有一个排序列表
        的System.out.println(songs2);
      }
   公共无效sortYear(){
        Collections.sort(songs2,SongComparator.byYear()); //现在我们有一个排序列表
        的System.out.println(songs2);
      }
   公共字符串的toString(){
      字符串结果=;
      的for(int i = 0; I&LT; songs2.size();我++){
         结果+ =+ songs2.get(ⅰ);
      }      返回结果;   }
}
类SongComparator实现比较&LT;宋&GT; {
   公共枚举订单{
      YEAR_SORT,RANK_SORT,ARTIST_SORT,TITLE_SORT
   }
   私人订购sortingBy;
   公共SongComparator(订购sortingBy){
      this.sortingBy = sortingBy;
   }
   公共静态SongComparator byTitle(){
       返回新SongComparator(SongComparator.Order.TITLE_SORT);
   }
   公共静态SongComparator byYear(){
       返回新SongComparator(SongComparator.Order.YEAR_SORT);
   }
   公共静态SongComparator byArtist(){
       返回新SongComparator(SongComparator.Order.ARTIST_SORT);
   }
   公共静态SongComparator byRank(){
       返回新SongComparator(SongComparator.Order.RANK_SORT);
   }   @覆盖
   公众诠释比较(宋松1,宋song2){
      开关(sortingBy){
      案例YEAR_SORT:
         返回Integer.compare(song1.year,song2.year);
      案例RANK_SORT:
         返回Integer.compare(song1.rank,song2.rank);
      案例ARTIST_SORT:
         返回song1.artist.compareTo(song2.artist);
      案例TITLE_SORT:
         返回song1.title.compareTo(song2.title);
      }
      抛出新的RuntimeException(
            实际上可达code,不能抛出);
   }}


解决方案

通过在你的文本文件数据库差不多37000首歌曲,并为用户访问它(按年,今年的范围,职级,职级显著多种方式-range,...),包括排序的可能性,我认为这几乎要求你pre-过程中你的歌,数据库与一次性只处理 - 一次一次的数据库是changed--曾经给你的用户查询反对的机会之前,优化您的数据。

(我在这里做的前提是你不能使用一个真正的数据库,这将是理想的解决方案)

我建议的第一件事就是分配一个唯一的密钥(ID),以每首歌曲,从 1 ,其中,code,应重新$ p $与长psented。这使数据库中的第一列。例如,称之为 agazillionsongs_with_id.txt

  2008年1〜50 Ashley Tisdale的,他说,她说:
2 2008年123 Taylor Swift的泪滴在我的吉他
3 2008年233指十一Paralyzer
2008年4 Paramore的258苦难业务
...
470 2007 251孟汉娜真正的朋友
2006年471碧昂斯1无可替代
...

现在创建额外的子表(索引),在单独的文本文件,每个文件的单纯指歌曲的关键。最简单的是为期一年的指数,它可以存储在一个名为 agazillionsongs_sub_year.txt

  2008年1
2008年2
2008年3
2008年4月
...
2007 470
...
2006年471
...

另外,你可以每年储存以这种形式(我preFER此格式)

  2008年1〜,2,3,4,...
2007年470,...
2006年471,...

无论哪种方式,这可以重新$ P $在code psented为 yearMap 对象,这是一个地图&LT;整数,清单&LT;宋&GT;&GT; ,其中的值是合适的歌曲对象的引用。一旦这些地图的创建,它们输出到文件很容易。

做到这一点也与排名: agazillionsongs_sub_rank.txt / rankMap / 地图&LT;整数,列表与LT;宋&GT;&GT;

索引的名字和头衔是麻烦 - 你的索引整个名称,从字面上或与模糊的一些概念,或者仅仅是个开始,...?这是一个困难而重要的概念。

越远,你可以采取这样的想法,你切片和切块数据,更快的用户可以查询数据库中的更多的方式。这是因为需要通过充分的歌曲数据库每次看书,把每一行成歌曲的对象,被淘汰。

相反,此pre-处理可以让你知道的究竟的该数据库中的行需要检索。所以,你可以忽略所有其他行并丢弃它们。

我希望这可以帮助你。

FOLLOW UP QUESTION HERE: Java: Printing Arraylist to Output File?

For some reason, it takes an extraordinary amount of time for the ArrayLists to be printed to the output file, usually 20-30 minutes. However, this only happens with the sort methods or the filterTitle or filterArtist methods (methods that concern String inputs). When I run filterRank or filterYear, it runs perfectly fine.

When I print the song2 ArrayList directly from the filter methods, the only thing that is printed is [], which means the ArrayList is empty, but it shouldn't be? And the filterRank and filterYear methods still work regardless of this. Somehow I think it's related, though.

Input file can be found here: http://staff.rentonschools.us/hhs/ap-comp-science/projects/download/agazillionsongs.txt?id=223098

Example sort method:

public void sortYear() {
   Collections.sort(songs2, SongComparator.byYear()); // now we have a sorted list
   System.out.println(songs2);
}

Example filter method (for strings)

public void filterArtist(String s) {
   int n = 0;
   if (n == 0) {
      System.out.println("Program is processing.");
      n++;
      for (Song song1 : songs2) {
         if ((!(((song1.artist).contains(s))))) {
            itemsToRemove.add(song1);
         }
      }
      songs2.removeAll(itemsToRemove);
      itemsToRemove.clear();
   }
   System.out.println(songs2);
}

Example filter method (for ints)

public void filterRank(Range r) {
   int n = 0;
   if (n == 0) {
      System.out.println("Program is processing.");
      n++;
      for (Song song1 : songs2) {
         if (song1.rank > (r.getMax()) || (song1.rank) < (r.getMin())) {
            itemsToRemove.add(song1);
         }
      }
      songs2.removeAll(itemsToRemove);
      itemsToRemove.clear();
   }
   System.out.println(songs2);
}

Code in main class for printing/output file

while (input.hasNextLine()) {
   int n = 0;
   SongCollection collection = new SongCollection(songs);
   String inputType = input.nextLine();
   String delims = "[ ]";
   String[] tokens = inputType.split(delims);
   for (int i = 0; i < tokens.length; i++) {
      n = 0;
      if (n == 0) {
         if ((tokens[i]).contains("year:")) {
            collection.filterYear(Range.parse(tokens[i]));
            n = 1;
         }// end of year loop
         if ((tokens[i]).contains("rank:")) {
            collection.filterRank(Range.parse(tokens[i]));
            n = 1;
         }// end of rank
         if ((tokens[i]).contains("artist:")) {
            collection.filterArtist(tokens[i]);
            n = 1;
         }// end of artist
         if ((tokens[i]).contains("title:")) {
            collection.filterTitle(tokens[i]);
            n = 1;
         }// end of title
         if ((tokens[i]).contains("sort:")) {
               if ((tokens[i]).contains("title")) {
                  collection.sortTitle();
                  n = 1;
               }// end of sort title
               if ((tokens[i]).contains("artist")) {
                  collection.sortArtist();
                  n = 1;
               }// end of sort artist
               if ((tokens[i]).contains("rank")) {
                  collection.sortRank();
                  n = 1;
               }// end of sort rank
               if ((tokens[i]).contains("year")) {
                  collection.sortYear();
                  n = 1;
               }// end of sort year
         }//end of sort
      }// end of for loop

   }// end of input.hasNextline loop
   final PrintStream console = System.out; //saves original System.out
   File outputFile = new File("output.txt"); //output file
   PrintStream out = new PrintStream(new FileOutputStream(outputFile)); //new FileOutputStream
   System.setOut(out); //changes where data will be printed
   System.out.println(collection.toString());

   System.setOut(console); //changes output to print back to console
   Scanner outputFileScanner = new Scanner(outputFile); //inputs data from file
   while ((outputFileScanner.hasNextLine())) { //while the file still has data
      System.out.println(outputFileScanner.nextLine()); //print
   }
   outputFileScanner.close();
   out.close();
}

Full code for compilation:

   import java.io.*;
   import java.io.File;
   import java.io.FileNotFoundException;
   import java.util.*;
   import java.util.Comparator;
   import java.util.Scanner;
   import java.util.StringTokenizer;

public class GazillionSongs {
   public static void main(String[] args) throws FileNotFoundException, IOException {
      System.out.println("Welcome to Java Song Collection!"); // greets the user
      System.out
      .println("This program sorts and filters large databases of popular songs."); // explains purpose of program
      System.out
      .println("This program is able to filter and sort by year, artist, title and rank.");
      System.out
      .println("Please enter a file that contains a database you wish to filter or sort. (i.e, alistofsongs.txt)"); // sample file = agazillionsongs.txt
      Scanner fileInput = new Scanner(System.in); //Scanner which accepts filename
      String filename = fileInput.nextLine();

      File f = new File(filename); //creates file from input
      /*error check for file here*/
      Scanner fileScanner = new Scanner(f); //inputs data from file

      ArrayList<Song> songs = new ArrayList<Song>();
      while ((fileScanner.hasNextLine())) {
         songs.add(Song.parse(fileScanner.nextLine()));
      }

      System.out
      .println("Please select which commands you would like to use for the program.");
      System.out
      .println("Please format your command like the following example: year:<year(s)> rank:<rank(s)> artist:<artist> title:<title> sortBy:<field>");
      System.out.println();
      System.out.println("You may pick any number of commands you want.");
      System.out
      .println("For years and rank, you may select a range of years or ranks.");
      System.out
      .println("For artists and titles, you may enter a partial name or title.");
      System.out.println("i.e, year:1983 rank:1");
      Scanner input = new Scanner(System.in);

      while (input.hasNextLine()) {
         int n = 0;
         SongCollection collection = new SongCollection(songs);
         String inputType = input.nextLine();
         String delims = "[ ]";
         String[] tokens = inputType.split(delims);
         for (int i = 0; i < tokens.length; i++) {
            n = 0;
            if (n == 0) {
               if ((tokens[i]).contains("year:")) {
                  collection.filterYear(Range.parse(tokens[i]));
                  n = 1;
               }// end of year loop
               if ((tokens[i]).contains("rank:")) {
                  collection.filterRank(Range.parse(tokens[i]));
                  n = 1;
               }// end of rank
               if ((tokens[i]).contains("artist:")) {
                  collection.filterArtist(tokens[i]);
                  n = 1;
               }// end of artist
               if ((tokens[i]).contains("title:")) {
                  collection.filterTitle(tokens[i]);
                  n = 1;
               }// end of title
               if ((tokens[i]).contains("sort:")) {
                     if ((tokens[i]).contains("title")) {
                        collection.sortTitle();
                        n = 1;
                     }// end of sort title
                     if ((tokens[i]).contains("artist")) {
                        collection.sortArtist();
                        n = 1;
                     }// end of sort artist
                     if ((tokens[i]).contains("rank")) {
                        collection.sortRank();
                        n = 1;
                     }// end of sort rank
                     if ((tokens[i]).contains("year")) {
                        collection.sortYear();
                        n = 1;
                     }// end of sort year
               }//end of sort
            }// end of for loop

         }// end of input.hasNextline loop
         final PrintStream console = System.out; //saves original System.out
         File outputFile = new File("output.txt"); //output file
         PrintStream out = new PrintStream(new FileOutputStream(outputFile)); //new FileOutputStream
         System.setOut(out); //changes where data will be printed
         System.out.println(collection.toString());

         System.setOut(console); //changes output to print back to console
         Scanner outputFileScanner = new Scanner(outputFile); //inputs data from file
         while ((outputFileScanner.hasNextLine())) { //while the file still has data
            System.out.println(outputFileScanner.nextLine()); //print
         }
         outputFileScanner.close();
         out.close();
      }
   }// end of main
}// end of class

class Song{
   public enum Order {Year, Rank, Title, Artist}
   public int year;
   public int rank;
   public String artist;
   public String title;

   public static Song parse(String s) {
      Song instance = new Song();
      StringTokenizer tokenizer = new StringTokenizer(s, "\t");
      instance.year = Integer.parseInt(tokenizer.nextToken());
      instance.rank = Integer.parseInt(tokenizer.nextToken());
      instance.artist = (tokenizer.nextToken());
      instance.title = (tokenizer.nextToken());
      return instance;
   }

   public int getYear() {
      return year;
   }

   public int getRank() {
      return rank;
   }

   public String getArtist() {
      return artist;
   }

   public String getTitle() {
      return title;

   }

   public String toString() {
      String output = "\n\nYear = " + year + "\nRank = " + rank + "\nArtist = "
            + artist + "\nTitle = " + title;
      return output;
   }

}
class Range {
   private int min;
   private int max;

   public Range() {
      System.out.println("Please wait.");
   }

   public static Range parse(String s) {
      Range instance = new Range(); // instance is created here so object
                              // variables may be accessed
      String field; // String to contain deleted part of user input
      StringTokenizer tokenizer = new StringTokenizer(s, "-");
      StringTokenizer tokenizer2 = new StringTokenizer(s, ":");// for separating "field:" from the
                                                   // other part of the String
      if (s.contains(":")) { // this deletes the "field:" of the user input so
                        // it does not interfere with the parsing
         field = (tokenizer2.nextToken());
         s = s.replace(field, "");
         s = s.replace(":", "");
      }
      if (s.contains("-")) {
         instance.min = Integer.parseInt(tokenizer.nextToken());
         instance.max = Integer.parseInt(tokenizer.nextToken());

      } else if (!(s.contains("-"))) {
         {
            instance.min = Integer.parseInt(s);
            instance.max = Integer.parseInt(s);
         }
      }
      System.out.println("Range max = " + instance.max);
      System.out.println("Range min = " + instance.min);
      return instance;
   }

   public boolean contains(int n) {
      if (n > min && n < max) { //if the number is contained in the range, method returns true.
         return true;
      } else if (n == min && n == max) {
         return true;
      } else {
         return false;
      }
   }

   public int getMin() {
      return min;
   }

   public int getMax() {
      return max;
   }
}
class SongCollection {
   ArrayList<Song> songs2;
   ArrayList<Song> itemsToRemove = new ArrayList<Song>(); // second collection
                                             // for items to
                                             // remove
   public SongCollection(ArrayList<Song> songs) { // constructor for SongCollection
      System.out.println("Test");
      this.songs2 = songs;
      }
   public void filterYear(Range r) {
      int n = 0;
      if (n == 0) {
         System.out.println("Program is processing.");
         n++;
         for (Song song1 : songs2) {
            if (song1.year > (r.getMax()) || (song1.year) < (r.getMin())) {
               itemsToRemove.add(song1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      System.out.println(songs2);
   }

   public void filterRank(Range r) {
      int n = 0;
      if (n == 0) {
         System.out.println("Program is processing.");
         n++;
         for (Song song1 : songs2) {
            if (song1.rank > (r.getMax()) || (song1.rank) < (r.getMin())) {
               itemsToRemove.add(song1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      System.out.println(songs2);
   }

   public void filterArtist(String s) {
      int n = 0;
      if (n == 0) {
         System.out.println("Program is processing.");
         n++;
         for (Song song1 : songs2) {
            if ((!(((song1.artist).contains(s))))) {
               itemsToRemove.add(song1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      System.out.println(songs2);
   }

   public void filterTitle(String s) {
      int n = 0;
      if (n == 0) {
         System.out.println("Program is processing.");
         n++;
         for (Song song1 : songs2) {
            if ((!(((song1.title).contains(s))))) {
            itemsToRemove.add(song1);
            }
         }
         songs2.removeAll(itemsToRemove);
         itemsToRemove.clear();
      }
      System.out.println(songs2);
   }

   public void sortTitle() {
        Collections.sort(songs2, SongComparator.byTitle()); // now we have a sorted list
        System.out.println(songs2);
      }
   public void sortRank() {
        Collections.sort(songs2, SongComparator.byRank()); // now we have a sorted list
        System.out.println(songs2);
      }
   public void sortArtist() {
        Collections.sort(songs2, SongComparator.byArtist()); // now we have a sorted list
        System.out.println(songs2);
      }
   public void sortYear() {
        Collections.sort(songs2, SongComparator.byYear()); // now we have a sorted list
        System.out.println(songs2);
      }
   public String toString() {
      String result = "";
      for (int i = 0; i < songs2.size(); i++) {
         result += " " + songs2.get(i);
      }

      return result;

   }
}
class SongComparator implements Comparator<Song> {
   public enum Order{
      YEAR_SORT, RANK_SORT, ARTIST_SORT, TITLE_SORT
   }
   private Order sortingBy;
   public SongComparator(Order sortingBy){
      this.sortingBy = sortingBy;
   }
   public static SongComparator byTitle() {
       return new SongComparator(SongComparator.Order.TITLE_SORT);
   }
   public static SongComparator byYear() {
       return new SongComparator(SongComparator.Order.YEAR_SORT);
   }
   public static SongComparator byArtist() {
       return new SongComparator(SongComparator.Order.ARTIST_SORT);
   }
   public static SongComparator byRank() {
       return new SongComparator(SongComparator.Order.RANK_SORT);
   }

   @Override
   public int compare(Song song1, Song song2) {
      switch (sortingBy) {
      case YEAR_SORT:
         return Integer.compare(song1.year, song2.year);
      case RANK_SORT:
         return Integer.compare(song1.rank, song2.rank);
      case ARTIST_SORT:
         return song1.artist.compareTo(song2.artist);
      case TITLE_SORT:
         return song1.title.compareTo(song2.title);
      }
      throw new RuntimeException(
            "Practically unreachable code, can't be thrown");
   }

}

解决方案

With almost 37,000 songs in your text-file database, and a significant number of ways for users to access it (by year, year-range, rank, rank-range, ...), including the possibility of sorting, I think it's almost required that you pre-process your song-database with a one-time-only process--once every time the database is changed--to optimize your data before ever giving your users the chance to query against it.

(I am making the assumption here that you can't use a real database, which would be the ideal solution)

The first thing I would recommend is to assign a unique key (ID) to each song, starting with 1, which, in code, should be represented with a long. Make this the first column in your database. For example, call it agazillionsongs_with_id.txt:

1 2008  50 Ashley Tisdale He Said, She Said
2 2008  123   Taylor Swift   Teardrops On My Guitar
3 2008  233   Finger Eleven  Paralyzer
4 2008  258   Paramore Misery Business
...
470  2007  251   Hannah Montana True Friend
471  2006  1  Beyonce  Irreplaceable
...

Now create additional sub-tables (indexes), in separate text files, each of which simply refer to the song's key. The simplest one is a year-index, which could be stored in a file called agazillionsongs_sub_year.txt:

2008 1
2008 2
2008 3
2008 4
...
2007 470
...
2006 471
...

Alternatively, you could store each year in this form (I prefer this format)

2008 1, 2, 3, 4, ...
2007 470, ...
2006 471, ...

Either way, this could be represented in code as a yearMap object, which is a Map<Integer,List<Song>>, where the value is a reference to the appropriate Song object. Once these maps are created, outputting them to file is easy.

Do this also with rank: agazillionsongs_sub_rank.txt / rankMap / Map<Integer,List<Song>>

Indexing by name and title is trickier--do you index the whole name, literally or with some concept of "fuzziness", or only the beginning, ...? It's a hard but important concept.

The farther you can take this idea, the more ways you slice-and-dice your data, the faster your users can query the database. This is because the need for reading through the full song-database each time, putting every line into a Song object, is eliminated.

Instead, this pre-processing allows you to know exactly which rows in the database need to be retrieved. So you can ignore all other lines and discard them.

I hope this helps you.

这篇关于ArrayList的打印输出到文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆