读取csv文件预订最多的房间

问题描述

我有一个大学毕业的项目来完成,基本上是从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]
======

Online demo

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...