问题描述
我有一个大学毕业的项目来完成,基本上是从Java的CSV文件返回一堆东西。
我从上次尝试中成功地完成了大部分工作,但是我坚持的一部分是如何读取CSV文件,但仅读取文件的特定部分:预订时间最多的房间在运行jmh并制作一个新的jar文件时显示在终端上。我的第一个尝试是硬编码,尽管可以用,但这并不是讲师想要的。任何帮助或定向指针都将是很棒的代码,这是讲师不想要的。
此外,CSV文件的格式为A)id B)房间名称C)日期D)时间E)预订时间F)人员预订
public String [] getTopRoomsBooked(int n){
HashMap<String,Integer> rooms = new HashMap<String,Integer>();
rooms.put("Gower",281);
rooms.put("Usk",291);
rooms.put("Wye",283);
rooms.put("Bala",282);
rooms.put("Pen y Fan",292);
rooms.put("Llangorse",290);
rooms.put("SNowdon",288);
rooms.put("Taff",296);
rooms.put("Cadair Idris",292);
for (String i : rooms.keySet()) {
System.out.println("Room name: " + i + " Amount of time: " + rooms.get(i));
}
System.out.println();
List<Integer> timeBooked = new ArrayList<>(rooms.values());
Collections.sort(timeBooked,Collections.reverSEOrder());
if (n == 1) {
System.out.println("RoomName : Taff " + timeBooked.get(n - 1));
} else if (n == 3) {
System.out.println("1: Taff " + timeBooked.get(n - 3));
System.out.println("2: Cadiar Idris " + timeBooked.get(n - 2));
System.out.println("3: Pen y Fan " + timeBooked.get(n - 1));
} else if (n == 5) {
System.out.println("1: Taff " + timeBooked.get(n - 5));
System.out.println("2: Cadair Idris " + timeBooked.get(n - 4));
System.out.println("3: Pen y Fan " + timeBooked.get(n - 3));
System.out.println("4: Usk " + timeBooked.get(n - 2));
System.out.println("5: Llangorse " + timeBooked.get(n - 1));
} else if (n == 9) {
System.out.println("1: Taff " + timeBooked.get(n - 9));
System.out.println("2: Cadair Idris " + timeBooked.get(n - 8));
System.out.println("3: Pen y Fan " + timeBooked.get(n - 7));
System.out.println("4: Usk " + timeBooked.get(n - 6));
System.out.println("5: Llangorse " + timeBooked.get(n - 5));
System.out.println("6: SNowden " + timeBooked.get(n - 4));
System.out.println("7: Wye " + timeBooked.get(n - 3));
System.out.println("8: Bala " + timeBooked.get(n - 2));
System.out.println("9: Gower " + timeBooked.get(n - 1));
}
return null;
}
解决方法
这可以使用Java 8流使用以下功能来实现:
-
Comparator.comparing(...).thenComparing()
可以按预订的时间值以相反的顺序,然后按照房间名称对Map.Entry<String,Integer>
的流进行排序 -
limit
的输出量 -
map
重新映射到房间名称(rooms
哈希图中的键) -
collect(Collectors.toList()).toArray(String[]::new)
将房间名称收集到String数组
假设rooms
哈希图填充在方法getTopRoomsBooked
之外并作为参数提供,让我们将其重写如下:
public static String[] getTopRoomsBooked(Map<String,Integer> rooms,int n) {
// just for the row id in inner print
AtomicInteger id = new AtomicInteger(1);
Comparator<Map.Entry<String,Integer>> byTime = Comparator.comparing(Map.Entry::getValue,Comparator.reverseOrder());
Comparator<Map.Entry<String,Integer>> byName = Comparator.comparing(Map.Entry::getKey);
return rooms.entrySet().stream()
.sorted(byTime.thenComparing(byName))
.limit(n)
// inner print
.peek(e -> System.out.printf("%d: %s %d%n",id.getAndIncrement(),e.getKey(),e.getValue()))
.map(Map.Entry::getKey)
.collect(Collectors.toList())
.toArray(String[]::new);
}
测试和输出
int[] arr = {1,3,5};
Arrays.stream(arr)
.forEach(a -> System.out.println("Top " + a + ":\n"
+ Arrays.toString(Main.getTopRoomsBooked(rooms,a))
+ "\n======\n"
));
//////////////////////////////////////////////////////////////////
1: Taff 296
Top 1:
[Taff]
======
1: Taff 296
2: Cadair Idris 292
3: Pen y Fan 292
Top 3:
[Taff,Cadair Idris,Pen y Fan]
======
1: Taff 296
2: Cadair Idris 292
3: Pen y Fan 292
4: Usk 291
5: Llangorse 290
Top 5:
[Taff,Pen y Fan,Usk,Llangorse]
======