有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用于两个非唯一值的java数据结构

我面临着在某个{}中阅读的问题,而这个{}对于这个数字来说也不是唯一的

该程序计算量非常大,在我的ide上执行得不太好,因此我面临使用正确数据结构的问题

目前,我已经创建了一个index,我将number读入一个HashMap,将date读入另一个HashMap。如果我需要的话,我只是在匹配它们。但是,读入采用两个函数,每个函数都有一个while循环

public HashMap<String,String> getEventDates() throws Exception {
    String csvFile = "C:\\Users\\test.csv";

    CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
    String [] line;
    HashMap<String, String> eventMap = new HashMap<String, String>();

    while ((line = reader.readNext()) != null) {            
        eventMap.put(line[15], line[13]);
    }

    reader.close();
    return eventMap;
}

public HashMap<String,String> getNumberToEventDates() throws Exception {
    String csvFile = "C:\\Users\\test.csv";

    CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
    String [] line;
    HashMap<String, String> isinMap = new HashMap<String, String>();

    while ((line = reader.readNext()) != null) {            
        isinMap.put(line[15], line[4]);
    }

    reader.close();
    return isinMap;
}

我应该使用哪种数据结构来提高性能?如何合并这两种方法

我感谢你的回答

更新

哦,我很抱歉

事实上,在每次while迭代之后line[15],这只是我创建的一个索引

如何合并这两个函数


共 (3) 个答案

  1. # 1 楼答案

    我认为您不应该使用两个函数,因为从文件读取速度较慢,而应该修改函数,如

    public HashMap<String, SimpleEntry<String,String>> getEventDatesAndNumber() throws Exception 
    {
        String csvFile = "C:\\Users\\test.csv";
    
        CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
        String [] line;
        HashMap<String, SimpleEntry<String,String>> eventMap = new HashMap<String, SimpleEntry<String,String>>();
    
        while ((line = reader.readNext()) != null) 
        {            
            eventMap.put(line[15], new SimpleEntry<String , String>(line[13],line[4]));
        }
    
        reader.close();
        return eventMap;
    }
    

    编辑 Tim B想法也不错,您有MapKey类,然后您将上面的方法更改为

    public HashMap<String, MapKey> getEventDatesAndNumber() throws Exception 
    

    然后进行必要的更改

  2. # 2 楼答案

    我将首先假设您的CSV数据是以如下某种合理的格式进行结构

    NUM_HEADER,DATE_HEADER
    NUM_VALUE,DATE_VALUE
    NUM_VALUE,DATE_VALUE
    

    假设上述情况属实,您基本上应该将CSV文件中的行转换为Java中的对象。通常具有与CSV文件中的值一一匹配的属性

    所以你的代码看起来像这样

    public Events getEvents() throws Exception {
        String csvFile = "C:\\Users\\test.csv";
    
        CSVReader reader = new CSVReader(new FileReader(csvFile), ';');
        String [] line;
        HashMap<String, String> eventMap = new HashMap<String, String>();
    
        while ((line = reader.readNext()) != null) {            
            events.put(line[15], new Event(line[13], line[4]));
        }
    
        reader.close();
        return events;
    }
    

    然后还需要一个新的值类来将这两个变量保存在一起

    class Event {
        private int num;
        private int date;
    
        public Event(int date, int num) {
            this.date = date;
            this.num = num;
        }
    
        // Use Your IDE To generate equals and hash code. This is important! Because we're going to put this value class into a Java collection
    }
    

    Java collections - overriding equals and hashCode

    最后是一个在一个好的服务提供者中保存值类的类

    class Events {
         private Map map = new HashMap<Integer, Event>;
    
         public put(int uniqueId, Event event) {
             map.put(uniqueId, event);
         }
    
         //Now you can offer any kind of domain specific services to the consumer of the Events class that you want.
    }
    

    我喜欢这种结构,因为它对客户端代码非常简单。很多复杂性和簿记都被锁在Event和Events类中。您还可以将验证放在那里,并提供许多方便的方法

    最后一步,仅根据您的用例,将所有内容包装到“事件”对象中是必要的。如果您只需要Map接口提供的函数,那么我不会包装它。如果您需要特定于您的域的其他功能,那么我将包装它。但一般来说,只要可能,我倾向于使用OO类。从客户机的角度来看,处理Events类比处理Map<foo,bar>类要清楚得多。它只是在语义上更有意义,这在帮助客户理解发生了什么方面会有很大的不同

  3. # 3 楼答案

    如果我理解正确的话,您的唯一索引是数字和日期的组合,然后您想查找一个从该值映射的值

    处理此问题的方法是创建一个包含数字和日期的MapKey对象:

    class MapKey {
       final int number;
       final Date date;
    
       // Use Your IDE To generate equals and hash code. This is important!
    }
    

    然后只需要一个Map<MapKey, Data>就可以通过

    map.get(new MapKey(number, date));
    

    如果您已经拥有MapKey对象,而不是一直在重新创建它,那么这将更快,但是如果您确实需要创建它,这并不是什么大问题

    实际上,再看一次,您似乎正在从一个值映射到两个值,因此,要实现这一点,可能是另一种方式:

    class Data {
       int number;
       Date date;
    
       // Generate constructor etc in IDE
    }
    
    Map<String, Data> map = new HashMap<>();
    

    然后只需使用一种方法,并将for循环更改为:

    while ((line = reader.readNext()) != null) {            
        eventMap.put(line[15], new Data(line[13], line[4]));
    }