简体   繁体   English

优化哈希图中的搜索时间

[英]optimising the search time in hashmap

I have a csv file which is hashmapped, whenever the user enter the city name(key) it will display all the details of that city. 我有一个混编的csv文件,每当用户输入城市名称(键)时,它将显示该城市的所有详细信息。 I have to optimize the search result time, everytime the it is reading the file(instead of only once) and displaying the values. 我必须优化搜索结果的时间,每次它正在读取文件(而不是一次)并显示值时。 The CSV files contains data like this : CSV文件包含以下数据:

city,city_ascii,lat,lng,country,iso2,iso3,admin_name,capital,population,id Malishevë,Malisheve,42.4822,20.7458,Kosovo,XK,XKS,Malishevë,admin,,1901597212 Prizren,Prizren,42.2139,20.7397,Kosovo,XK,XKS,Prizren,admin,,1901360309 Zubin Potok,Zubin Potok,42.9144,20.6897,Kosovo,XK,XKS,Zubin Potok,admin,,1901608808 城市,city_ascii,纬度,国家,国家,iso2,iso3,admin_name,资本,人口,idMalishevë,马里舍夫,42.4822,20.7458,科索沃,XK,XKS,马里舍夫,admin,1901597212普里兹伦,普里兹伦,42.2139,20.7397,科索沃,XK,XKS,Prizren,admin,1901360309 Zubin Potok,Zubin Potok,42.9144,20.6897,科索沃,XK,XKS,Zubin Potok,admin,1901608808

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.io.IOException;
public class CSVFileReaders{
public static void main(String[] args) {
    String filePath = "C:\\worldcities1.csv";
    Scanner in = new Scanner(System.in);                                      
    System.out.println(" \n Enter the City name to be Searched :   \n _> ");
    long start = System.currentTimeMillis();
    String searchTerm = in.nextLine();
    readAndFindRecordFromCSV(filePath, searchTerm);
    long end = System.currentTimeMillis(); 
    System.out.println(" \n It took " + (end - start) + " Milli Seconds to search the result \n");
    in.close();
}

public static void readAndFindRecordFromCSV( String filePath, String searchTerm) {
    try{            
        HashMap<String,ArrayList<String>> cityMap = new HashMap<String,ArrayList<String>>();        
        Scanner x = new Scanner (new File(filePath),"UTF-8");
        String city= "";
        while(x.hasNextLine()) {
        ArrayList<String> values = new ArrayList<String>();
        String name  = x.nextLine();
        //break each line of the csv file to its elements
        String[] line = name.split(",");
        city = line[1];
            for(int i=0;i<line.length;i++){
                values.add(line[i]);            
            }
        cityMap.put(city,values);       
        }
        x.close();
        //Search the city
        if(cityMap.containsKey(searchTerm)) {

                System.out.println("City name is : "+searchTerm+"\nCity details are accordingly in the order :"
                                    + "\n[city , city_ascii , lat , lng , country , iso2 , iso3 , admin_name , capital , population , id] \n"
                                    +cityMap.get(searchTerm)+"");

            }           
        else {
            System.out.println("Enter the correct City name");
        }                       
    }
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}` }`

the time should be optimized and every time i search it is reading the entire file(which should happen) 时间应该被优化,并且每次我搜索它时都在读取整个文件(应该发生)

Currently you mix the map initialization inside the search function. 当前,您在搜索功能中混合了地图初始化。
You don't want that. 你不要那样
First, init the map, then use it in the search function. 首先,初始化地图,然后在搜索功能中使用它。
To do that, extract a method for statements that instantiate and value the map and then refactor the readAndFindRecordFromCSV() method so that it accepts a Map as additional parameter : 为此,请为实例化并为地图赋值的语句提取一个方法,然后重构readAndFindRecordFromCSV()方法,使其接受Map作为附加参数:

 public static void readAndFindRecordFromCSV( String filePath, String searchTerm,  HashMap<String,ArrayList<String>> dataByCity) {...}

With refactoring IDE features, it should be simple enough : "extracting method" then "change signature". 使用重构IDE功能,它应该足够简单:“提取方法”然后“更改签名”。

Here is a code (not tested at runtime but tested at compile time) that splits the logical in separated tasks and also rely on instance methods : 这是一个代码(未在运行时进行测试,但在编译时进行了测试),该代码将逻辑拆分为多个单独的任务,并且还依赖于实例方法:

public class CSVFileReaders {

    private final String csvFile;
    private HashMap<String, ArrayList<String>> cityMap;
    private final Scanner in = new Scanner(System.in);

    public static void main(String[] args) {
        String filePath = "C:\\worldcities1.csv";
        CSVFileReaders csvFileReaders = new CSVFileReaders(filePath);
        csvFileReaders.createCitiesMap();
        csvFileReaders.processUserFindRequest(); // First search
        csvFileReaders.processUserFindRequest(); // Second search
    }


    public CSVFileReaders(String csvFile) {
        this.csvFile = csvFile;
    }

    public void createCitiesMap() {
        cityMap = new HashMap<>();
        try (Scanner x = new Scanner(new File(csvFile), "UTF-8")) {
            String city = "";
            while (x.hasNextLine()) {
                ArrayList<String> values = new ArrayList<String>();
                String name = x.nextLine();
                //break each line of the csv file to its elements
                String[] line = name.split(",");
                city = line[1];
                for (int i = 0; i < line.length; i++) {
                    values.add(line[i]);
                }
                cityMap.put(city, values);
            }
            x.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }


    public void processUserFindRequest() {

        System.out.println(" \n Enter the City name to be Searched :   \n _> ");
        long start = System.currentTimeMillis();
        String searchTerm = in.nextLine();
        long end = System.currentTimeMillis();
        System.out.println(" \n It took " + (end - start) + " Milli Seconds to search the result \n");
        //Search the city
        if (cityMap.containsKey(searchTerm)) {
            System.out.println("City name is : " + searchTerm + "\nCity details are accordingly in the order :"
                                       + "\n[city , city_ascii , lat , lng , country , iso2 , iso3 , admin_name , capital , population , id] \n"
                                       + cityMap.get(searchTerm) + "");
        } else {
            System.out.println("Enter the correct City name");
        }
    }
}

The interesting part is here : 有趣的部分在这里:

String filePath = "C:\\worldcities1.csv";
CSVFileReaders csvFileReaders = new CSVFileReaders(filePath);
csvFileReaders.createCitiesMap();
csvFileReaders.processUserFindRequest(); // First search
csvFileReaders.processUserFindRequest(); // Second search

The logical is clearer now. 现在,逻辑更加清晰了。

Why do you create / load the CSV into a HashMap with every search ? 为什么每次搜索时都将CSV创建/加载到HashMap中? Just create the HashMap only once in the beginning , and then on every search just check whether it exists in the HashMap, eg move the read part into a separate method : 开始只创建一次 HashMap,然后在每次搜索中只需检查它是否存在于HashMap中,例如将读取的部分移到单独的方法中:

HashMap<String,ArrayList<String>> cityMap = new HashMap<String,ArrayList<String>>(); 

public static void readCSVIntoHashMap( String filePath) {
    try{            

        Scanner x = new Scanner (new File(filePath),"UTF-8");
        String city= "";
        while(x.hasNextLine()) {
        ArrayList<String> values = new ArrayList<String>();
        String name  = x.nextLine();
        //break each line of the csv file to its elements
        String[] line = name.split(",");
        city = line[1];
            for(int i=0;i<line.length;i++){
                values.add(line[i]);            
            }
        cityMap.put(city,values);       
        }
        x.close();
    ...
    }

Then have a separate method for searching : 然后有一个单独的搜索方法:

public static void search(String searchTerm) {
  if(cityMap.containsKey(searchTerm)) {
  ...
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM