2016-05-26 53 views
1

我需要在scala上製作一些java ArrayListscala sortWith not工作

它正在排序類的方法,files - 字段。要使用ArrayList心中已經進口的java.util.ArrayList和scala.collection.JavaConversions._

other imports ... 
import java.io.File 
import java.util.ArrayList 
import scala.collection.JavaConversions._ 

class SortReplays(val files:ArrayList[File]) { 
def sort(kindOfSort:String) = { 
    kindOfSort match { 
     case "name" => files.sortWith(compareFileNames); 
     case "length" => files.sortWith(compareGameLength); 
     case "date" => files.sortWith(compareGameDates); 
    } 
    } 

這是比較器之一,它也是SortReplays的方法

def compareGameLength(file1:File, file2:File) = { 
    val length1:Long = ReplayViewerController.getGameLength(file1) 
    val length2:Long = ReplayViewerController.getGameLength(file2) 
    length1 < length2 
    } 

這是我做java中

Service.out("scala sorting by length"); 
     long t1 = System.currentTimeMillis(); 
     ArrayList<File> fileList = new ArrayList<File>(Arrays.asList(files)); 
     SortReplays sort = new SortReplays(fileList); 
     sort.sort("length"); 
     Service.out("scala sort by length, time spend: " + (System.currentTimeMillis() - t1)); 
     try { 
     controller.refreshLengths(fileList.toArray(new File[0])); 
     controller.refreshReplays(fileList.toArray(new File[0])); 
     } catch (Exception e1) { 
     e1.printStackTrace(); 
     } 

我已經預計到的文件進行排序 - 但它不會發生,時間花費,但名單沒有任何改變。 此外,我已經做了在Java

public void sortLengths(ArrayList<File> files) { 
    Collections.sort(files, new Comparator<File>() { 

     @Override 
     public int compare(File arg0, File arg1) { 
     long l1; 
     long l2; 
     try { 
      l1 = getGameLength(arg0); 
      l2 = getGameLength(arg1); 
      if(l1 < l2) 
      return -1; 
      else if(l1 == l2) 
      return 0; 
      else 
      return 1; 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      return 0; 
     } 
     } 

    }); 
    } 

相同,它將按預期工作

+5

'sortWith'方法不排序,它返回一個排序的序列而不修改原始數據。 – Eastsun

+0

對收集API的工作方式存在嚴重誤解,關於不可變性 – cchantep

回答

2

的問題是,在files.sortWith回報SortReplays.sort一個Seq的電話,但不修改files列表。

要解決此問題,您需要:

首先,從def sort返回一個Java List。可以通過添加隱式轉換器來解決:

import scala.collection.JavaConversions._ 
import scala.collection.JavaConverters._ 

...

private implicit def toJavaList[T](seq: Seq[T]): util.List[T] = { 
    new util.ArrayList(seq.asJavaCollection) 
} 

def sort(kindOfSort: String): util.List[File] = { 
    kindOfSort match { 
    case "name" => files.sortWith(compareFileNames); 
    case "length" => files.sortWith(compareGameLength); 
    case "date" => files.sortWith(compareGameDates); 
    } 
} 

順便說一句,這是Scala中的一個很好的做法,指定公共職能明確的返回類型(: util.List[File]在這種情況下)。

ArrayList聲明也應改爲List,尊重程序對界面的原則。

其次,在Java端代碼,有些變化是必要的:

SortReplays sort = new SortReplays(Arrays.asList(files)); 
List<File> fileList = sort.sort("length"); 
Service.out("scala sort by length, time spend: " + (System.currentTimeMillis() - t1)); 
try { 
    controller.refreshLengths(fileList.toArray(new File[0])); 
    controller.refreshReplays(fileList.toArray(new File[0])); 
} catch (Exception e1) { 
    e1.printStackTrace(); 
} 

BTW,避免受涼Exception,這是醜陋的。