【发布时间】:2016-12-22 02:13:26
【问题描述】:
似乎类似于之前回答的问题:Java 8 stream group by min and max
其实不然!
我有一个三列的表:
LogId, StartTime, EndTime
现在我们有多个具有不同 StartTime 和 EndTime 的 LogId 条目
问题是:
我所有的列都是字符串,所以如何根据它们的值计算任何列的最小值或最大值。
我需要通过 LogId 找出 min(StartTime)、max(EndTime) 组到单个 Stream 中。
如何在 java 8 中使用流以最少的代码和最大的效率来实现这一点。
附上示例类:
public class Log {
private static final String inputFileName = "D:\\path\\to\\Log.csv";
private static final String outputFileName = "D:\\path\\to\\Output\\Log.csv";
private static List<Log> logList = null;
private static Map<String, List<Log>> groupByLogId = new HashMap<String, List<Log>>();
private String log_Id;
private String startTime;
private String endTime;
public static Map<String, List<Log>> createLogMap() throws IOException {
Function<String, Log> mapToLog = (line) -> {
String[] p = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
Log log = new Log(p[0],p[1],
p[2]);
return log;
};
InputStream is = null;
BufferedReader br = null;
is = new FileInputStream(new File(inputFileName));
br = new BufferedReader(new InputStreamReader(is));
logList = br.lines()
.skip(1)
.map(mapToLog)
.collect(Collectors.toList());
logList.stream().forEach(System.out::println);
groupByLogId = logList.stream()
.collect(Collectors.groupingBy(Log::getLog_Id));
for (Entry<String, List<Log>> entryForLog : groupByLogId.entrySet()) {
System.out.println(" Entity Id " + entryForLog.getKey()
+ " | Value : " + entryForLog.getValue());
}
br.close();
return groupByLogId;
}
public String getLog_Id() {
return log_Id;
}
public void setLog_Id(String log_Id) {
this.log_Id = log_Id;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public static List<Log> getLoglist() {
return logList;
}
public Log(String log_Id, String startTime, String endTime) {
super();
this.log_Id = log_Id;
this.startTime = startTime;
this.endTime = endTime;
}
@Override
public String toString() {
return (new StringBuffer()
.append(log_Id).append(",")
.append(startTime).append(",")
.append(endTime)
).toString();
}
}
非常感谢任何帮助,
预期输出:
LogId: logid,min(StartTime),max(EndTime)
【问题讨论】:
-
"如何在 java 8 中使用流以最少的代码和最大的效率来实现这一点。" - 我觉得它太宽泛了,请尝试更具体地回答您的问题。
-
尝试在
group之前使用map到int/long -
那个代码看起来古老。您应该使用
StringBuilder而不是StringBuffer,但实际上,简单地使用log_Id+","+startTime+","+endTime会自动为您带来好处。您更复杂的toString()实现与简单表达式相比没有任何好处。此外,您应该使用try( …) { … }语句来管理资源。无需手动调用close(),异常情况下关闭不正确的问题就消失了。此外,您不再需要重复类型参数:groupByLogId=new HashMap<>()将根据变量推断类型。
标签: java java-8 java-stream