使用数组作为hashmap java的关键

时间:2017-04-30 09:25:21

标签: java arrays hashmap key

我有一个方法可以将一些值(从excel文件中获取)放入一个以数组为键的hashmap

public HashMap<List<String>, List<String[]>> sbsBusServiceDataGnr() throws 
    IOException
{
    System.out.println(engine.txtY + "Processing HashMap "
        + "sbsBusServiceData..." + engine.txtN);
    int counterPass = 0, counterFail = 0, stopCounter = 0;
    String dataExtract, x = "";
    String[] stopInfo = new String[3];
    List<String[]> stopsData = new ArrayList<String[]>();
    List<String> serviceNum = new Vector<String>();

    HashMap<List<String>, List<String[]>> sbsBusServiceData = 
        new HashMap<List<String>, List<String[]>>();
    String dataPath = this.dynamicPathFinder(
        "Data\\SBS_Bus_Routes.csv");
    BufferedReader sbsBusServiceDataPop = new BufferedReader(
        new FileReader(dataPath));

    sbsBusServiceDataPop.readLine();
    //Skips first line
    while ((dataExtract = sbsBusServiceDataPop.readLine()) != null) {
        try {
            String[] dataParts = dataExtract.split(",", 5);
            if (!dataParts[4].equals("-")){
                if (Double.parseDouble(dataParts[4]) == 0.0){
                    sbsBusServiceData.put(serviceNum, stopsData);
                    String serviceNum1 = "null", serviceNum2 = "null";
                    if(!serviceNum.isEmpty()){
                        serviceNum1 = serviceNum.get(0);
                        serviceNum2 = serviceNum.get(1);
                    }
                    System.out.println("Service Number " + serviceNum1 
                        + ":" + serviceNum2 + " with " + stopCounter 
                        + " stops added.");
                    stopCounter = 0;
                    //Finalizing previous service

                    serviceNum.Clear();
                    serviceNum.add(0, dataParts[0]);
                    serviceNum.add(1, dataParts[1]);
                    //Adding new service
                }
            }
            stopInfo[0] = dataParts[2];
            stopInfo[1] = dataParts[3];
            stopInfo[2] = dataParts[4];
            stopsData.add(stopInfo);
            //Adding stop to service

            stopCounter++;
            counterPass++;
            }
        catch (Exception e) {
            System.out.println(engine.txtR + "Unable to process "
                + dataExtract + " into HashMap sbsBusServiceData." 
                + engine.txtN + e);
            counterFail++;
        }
    }
    sbsBusServiceDataPop.close();

    System.out.println(engine.txtG + counterPass + " number of lines"
        + " processed into HashMap sbsBusServiceData.\n" + engine.txtR
        + counterFail + " number of lines failed to process into "
        + "HashMap sbsBusServiceData.");

    return sbsBusServiceData;
}
//Generates sbsBusServiceDataGnr HashMap : 15376 Data Rows
//HashMap Contents: {ServiceNumber, Direction}, 
//    <{RouteSequence, bsCode, Distance}>

这个方法适用于将值放入hashmap但是当我尝试调用hashmap时,我似乎无法从hashmap中获取任何值,总是存在nullpointerexception

List<String> sbsTest = new Vector<String>();
    sbsTest.add(0, "10");
    sbsTest.add(1, "1");
    System.out.println(sbsBusServiceData.get(sbsTest));
    try{
        List<String[]> sbsServiceResults = sbsBusServiceData.get(sbsTest);
        System.out.println(sbsServiceResults.size());
        String x = sbsServiceResults.get(1)[0];
        System.out.println(x);
    } catch(Exception e){
        System.out.println(txtR + "No data returned" + txtN + e);
    }

这是我从以下网址读取数据的文件样本:

SBS

如何让hashmap返回我想要的值?

2 个答案:

答案 0 :(得分:3)

数组不适合HashMap中的键,因为数组不会覆盖Object的{​​{1}}和equals方法(这意味着包含两个不同的数组实例) hashCode)将完全相同的元素视为不同的键。

替代方法是使用HashMap代替List<String>作为String[]的密钥,或使用HashMap并传递自定义TreeMap<String[]>到构造函数。

答案 1 :(得分:0)

如果数组大小固定,那么我发布的示例可能会有用。 在这里,我创建了两个对象,一个是食品,另一个是产品。 这里的Food对象是使用和添加的方法来获取字符串数组。

public class Product {

private String productName;
private String productCode;

    public Product(String productName, String productCode) {
        this.productName = productName;
        this.productCode = productCode;
    }

    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public String getProductCode() {
        return productCode;
    }
    public void setProductCode(String productCode) {
        this.productCode = productCode;
   }    
}

食品模型类:用作对象而不是String []并实现String []功能。

public class Food implements Comparable<Food> {

private String type;
private String consumeApproach;

    public Food(String type, String consumeApproach) {
        this.type = type;
        this.consumeApproach = consumeApproach;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getConsumeApproach() {
        return consumeApproach;
    }

    public void setConsumeApproach(String consumeApproach) {
        this.consumeApproach = consumeApproach;
    }

    public String[] FoodArray() {
        return new String[] { this.type, this.consumeApproach };
    }
//Implement compareTo method as you want.
    @Override
    public int compareTo(Food o) {
        return o.getType().compareTo(this.type);
    }
}

使用HashMap示例

public class HashMapKeyAsArray {

public static void main(String[] args) {
    HashMap<Food,List<Product>> map = dataSetLake();
    map.entrySet().stream().forEach(m -> {
        String[] food = m.getKey().FoodArray();
        Arrays.asList(food).stream().forEach(f->{
            System.out.print(f + "       ");
        });
        System.out.println();
        List<Product> list = m.getValue();
        list.stream().forEach(e -> {
            System.out.println("Name:" + e.getProductName() + "     Produc Code:" + e.getProductCode());
        });
        System.out.println();
    });
}

private static HashMap<Food,List<Product>> dataSetLake(){
    HashMap<Food,List<Product>> data = new HashMap<>();

    List<Product> fruitA = new ArrayList<>();

    fruitA.add(new Product("Apple","123"));
    fruitA.add(new Product("Banana","456"));
    List<Product> vegetableA = new ArrayList<>();
    vegetableA.add(new Product("Potato","999"));
    vegetableA.add(new Product("Tomato","987"));

    List<Product> fruitB = new ArrayList<>();

    fruitB.add(new Product("Apple","123"));
    fruitB.add(new Product("Banana","456"));
    List<Product> vegetableB = new ArrayList<>();
    vegetableB.add(new Product("Potato","999"));
    vegetableB.add(new Product("Tomato","987"));

    Food foodA = new Food("Fruits","Read To Eat");
    Food foodB = new Food("Vegetables","Need To Cook");
    Food foodC = new Food("VegetablesC","Need To Cook C");


    data.put(foodA, fruitB);
    data.put(foodB, vegetableB);

    data.put(foodA, fruitA);
    data.put(foodC, vegetableA);

    return data;
}

使用TreeMap示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeMap;

public class TreeMapKeyAsArray {
    public static void main(String[] args) {
        TreeMap<Food, List<Product>> map = dataSetLake();
        map.entrySet().stream().forEach(m -> {
        String[] food = m.getKey().FoodArray();
        Arrays.asList(food).stream().forEach(f->{
            System.out.print(f + "       ");
        });
        System.out.println();
        List<Product> list = m.getValue();
        list.stream().forEach(e -> {
            System.out.println("Name:" + e.getProductName() + "     Produc Code:" + e.getProductCode());
        });
        System.out.println();
    });
}

private static TreeMap<Food, List<Product>> dataSetLake() {
    TreeMap<Food, List<Product>> data = new TreeMap<>();

    List<Product> fruitA = new ArrayList<>();

    fruitA.add(new Product("Apple", "123"));
    fruitA.add(new Product("Banana", "456"));
    List<Product> vegetableA = new ArrayList<>();
    vegetableA.add(new Product("Potato", "999"));
    vegetableA.add(new Product("Tomato", "987"));

    List<Product> fruitB = new ArrayList<>();

    fruitB.add(new Product("Apple", "123"));
    fruitB.add(new Product("Banana", "456"));
    List<Product> vegetableB = new ArrayList<>();
    vegetableB.add(new Product("Potato", "999"));
    vegetableB.add(new Product("Tomato", "987"));

    Food foodA = new Food("Fruits", "Read To Eat");
    Food foodB = new Food("Vegetables", "Need To Cook");

    data.put(foodA, fruitB);
    data.put(foodB, vegetableB);

    data.put(foodA, fruitA);
    data.put(foodB, vegetableA);
    return data;
    }
}