java - 使用 Java 解析 .csv 文件时面临的问题
问题描述
我有一个 .csv 文件,如下所示。它有 2 列URL
和timestamp
. 假设 URL 是字母数字和 UTC 日期/时间。
URL,timestamp
URL1,2018-12-09T14:19:00+00:00
URL1,2018-12-09T10:13:00+00:00
URL2,2018-12-09T07:25:00+00:00
URL3,2018-12-09T06:19:00+00:00
URL2,2018-12-08T22:03:00+00:00
URL3,2018-12-08T21:30:00+00:00
URL3,2018-12-08T09:30:00+00:00
URL2,2018-12-07T23:30:00+00:00
我想查找给定日期作为输入,访问次数最多的 URL。
eg : Input : 2018-12-09
Output : URL1
Explaination: We can see above that URL1 has 2 entries on 2018-12-09 ,so it was visited the most times on that day.
我实现上述的想法是使用 aHashMap<String , List<String>>
来存储date as Key
and URL's as List of values for that Key
。
我在解析这个文件时遇到了问题。我怎样才能
解析时间戳列并将日期存储
Key
在地图中,因为有重复的日期?我假设一旦我们可以缩小上述范围,我们就可以将 URL 作为值存储在该键的列表中。我们可以从映射中提取对应键的值到一个数组,然后检查大多数重复的 URL。这是正确的方法吗?
我没有为此使用任何第 3 方库
高度赞赏以上任何输入。
解决方案
我建议您创建一个自定义类型,例如Visit
如下所示,以结构化方式处理记录。您可以使用标准 Java I/O 库或一些专门的库从文件中读取记录并填充Visit
对象。为此,我建议您使用流行的opencsv 库。无论您以何种方式填充Visit
对象并创建List<Visit>
这些对象,都可以使用 Java Stream API 来处理列表。为了这个演示,我List<Visit>
用你的问题中显示的记录创建了一个。
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
class Visit {
private String url;
private OffsetDateTime dateTime;
public Visit(String url, OffsetDateTime dateTime) {
this.url = url;
this.dateTime = dateTime;
}
public String getUrl() {
return url;
}
public OffsetDateTime getDateTime() {
return dateTime;
}
}
public class Main {
public static void main(String[] args) {
List<Visit> list = List.of(
new Visit("URL1", OffsetDateTime.parse("2018-12-09T14:19:00+00:00")),
new Visit("URL1", OffsetDateTime.parse("2018-12-09T10:13:00+00:00")),
new Visit("URL2", OffsetDateTime.parse("2018-12-09T07:25:00+00:00")),
new Visit("URL3", OffsetDateTime.parse("2018-12-09T06:19:00+00:00")),
new Visit("URL2", OffsetDateTime.parse("2018-12-08T22:03:00+00:00")),
new Visit("URL3", OffsetDateTime.parse("2018-12-08T21:30:00+00:00")),
new Visit("URL3", OffsetDateTime.parse("2018-12-08T09:30:00+00:00")),
new Visit("URL2", OffsetDateTime.parse("2018-12-07T23:30:00+00:00"))
);
// Tests
System.out.println(mostVisitedUrlByDate(list, LocalDate.of(2018, 12, 9)));
System.out.println(mostVisitedUrlByDate(list, LocalDate.now(ZoneOffset.UTC)));
System.out.println(mostVisitedUrlByDate(null, LocalDate.of(2018, 12, 9)));
}
static String mostVisitedUrlByDate(List<Visit> list, LocalDate date) {
return list!=null ? list.stream() // Traverse list if it is not null
.filter(e -> e.getDateTime().toLocalDate().equals(date))
// Get a Map<String, List<Visit>> where value is the list of Visit objects grouped on the URL
.collect(Collectors.groupingBy(Visit::getUrl))
.values()
// Stream of values of Map obtained as a result of grouping
.stream()
// Find the value i.e. List<Visit> of largest size
.max(Comparator.comparing(List::size))
//A List<Visit> with a default Visit object
.orElse(List.of(new Visit("Unknown", OffsetDateTime.now(ZoneOffset.UTC))))
// All Visit elements in the value have same URL. Get the URL of the first value
.get(0)
.getUrl()
// Return "Unknown" if list is null
:"Unknown";
}
}
输出:
URL1
Unknown
Unknown
我在代码中添加了足够多的注释,以便您更容易理解。另外,我对该方法进行了三个测试调用,mostVisitedUrlByDate
以便您可以清楚地了解每个方法调用的Stream
目的Optional
。
推荐阅读
- nlp - 无法从“变压器”导入“AutoModelForSequenceClassification”
- oracle - 使用加密凭据的 Powershell Oracle DB 连接
- reactjs - React,避免在一个条件下渲染两次
- azure-devops - 如何更改 Azure Devops 的行为以将使用 DataTestMethod 属性运行的测试报告为单独的测试
- npm - 执行 npm install 时 npm ERR 代码 EPERM syscall unlink
- firebase - 检索数组的数据
- firebase - 代码文件有问题。我不小心删除了它并希望它回来
- django - 如何在 html 模板中显示 djago 验证错误消息?
- asp.net - Visual Studio 2019:JS 文件未被识别为待更改,而其他文件被识别
- point-clouds - 以有效的方式将点从一个 PCL 移到另一个