2017-09-01 3 views
0

コンマ区切り入力の平均使用してJavaの上にある特定の列の値を持つ行が、私はいくつかのファイルがどのようにファイル

TIMESTAMP,COUNTRYCODE,RESPONSETIME 
    1544190995,US,500 
    1723922044,GB,370 
    1711557214,US,750 

どのようにすることによって行をフィルタリングすることができ、以下のようにコンマ区切り形式でいくつかのデータを持っていると仮定フィルタリングすることができRESPONSETIMEは平均を上回っていますか?つまり、RESPONSETIMEの平均は526です。したがって、526より大きいRESPONSETIMEを持つすべての行を表示する必要があります。データラインは特定の順序であることが保証されていません。 RESPONSETIMEが平均を上回っています)?

現在、私は以下のように平均を求めています。同じ方法でフィルタを適用してコレクションとして返すことはできますか?私の理解によれば、同じ方法でファイルを2回読むことはできません。

 public static Collection<?> filterByResponseTimeAboveAverage(Reader source) { 
      BufferedReader br = new BufferedReader(source); 
      String line = null; 
      Collection<String> additionalList = new ArrayList<String>(); 
      int iteration = 0; 
      String[] myArray = null; 
      long count=0; 
      long responseTime=0; 
      long sum=0; 
      int numOfResponseTime=0; 
      long average=0; 
      List<String> myList = new ArrayList<String>(); 
      try 
      { 
       while ((line = br.readLine()) != null) { 
        System.out.println("Inside while"); 
        if (iteration == 0) { 
         iteration++; 
         continue; 
        } 
        myArray = line.split(","); 
        for (String eachval:myArray) 
        { 

         boolean isNumeric = eachval.chars().allMatch(x -> Character.isDigit(x)); 
//since input dataline is not guaranted to be in any particular order I am finding RESPONSETIME like this 
         if (isNumeric) 
         { 
         count=eachval.chars().count(); 

         if (count<10) 
         { 
          responseTime=Integer.parseInt(eachval); 
          sum=sum+responseTime; 
          numOfResponseTime++; 
         } 
        } 
         myList.add(eachval); 
        } 

       } 
        average=sum/numOfResponseTime; 
        System.out.println("Average -- "+average); 
         --------------- 
         --------------- 
    } 

答えて

0

どのようにしてフィルタを適用し、同じメソッド内のコレクションとして返すことができますか? 同じメソッド内で二回ファイルを読み込むことがその可能性はない私の理解あたりとして

使用Java 8 streams and lambdas

2

これは効率的ではないので、これを行うべきではありません。


主に次の2つの方法があります。

最適化された方法:ファイルからすべての値を読み取る

  • RESPONSETIMEの平均値を計算します。
  • フィルタリング値平均

の上にあなたはソースから取得するために、filterByResponseTimeAboveAverage()によって呼び出さプライベートメソッドの両方のすべての値を導入し、それらの平均値を計算することができます。

機能的な方法(オーバーヘッドでもう少し高価な):

  • RESPONSETIMEの平均値を計算するために、ファイル
  • 使用IntStream.average()からすべての値を読み取ります。

    double average = list 
           .stream()    
           .mapToInt(MyObject::getAverage) 
           .average() 
           .getAsDouble(); 
    
    List<MyObject> filteredElements = list 
           .stream()    
           .filter(o-> o.getAverage() > average) 
           .collect(Collectors.toList()); 
    
    :第最後のステップの平均

上記

  • フィルタリング値が、それは次のようであってもよいです
  • 関連する問題