如何使用java输入逗号分隔文件来过滤具有高于平均值的特定列值的行

时间:2017-09-01 11:09:49

标签: java csv lambda java-8 generic-collections

假设我有一些文件包含逗号分隔格式的数据,如下所示

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

如何使用java过滤RESPONSETIME的行数高于平均值?即此处RESPONSETIME的平均值为526。所以我需要显示RESPONSETIME大于526的所有行。这些数据线不保证按任何特定顺序排列。可以我们在一个方法中做两个(找到平均值和过滤行的RESPONSETIME高于平均值)?

目前我发现平均值如下。如何在同一方法中应用过滤器并将其作为集合返回?根据我的理解,在同一方法中无法读取文件两次。

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

2 个答案:

答案 0 :(得分:2)

  

根据我的理解,内部无法读取文件两次   同样的方法。

你可以,但你不应该这样做,因为效率不高。

您主要有两种处理方式。

优化方式:

  • 从文件中读取所有值并计算RESPONSETIME的平均值。
  • 过滤高于平均值
  • 的值

您可以引入filterByResponseTimeAboveAverage()调用的私有方法来检索源中的所有值并计算它们的平均值。

功能方式(开销稍微贵一点):

  • 读取文件中的所有值
  • 使用IntStream.average()计算RESPONSETIME的平均值。
  • 过滤高于平均值
  • 的值

对于第二步也是最后一步,它可能是:

double average = list
                .stream()             
                .mapToInt(MyObject::getAverage)
                .average()
                .getAsDouble();

List<MyObject> filteredElements = list
                .stream()             
                .filter(o-> o.getAverage() > average)
                .collect(Collectors.toList());  

答案 1 :(得分:0)

  

如何在同一方法中应用过滤器并将其作为集合返回?

使用Java 8 streams and lambdas