1

i have a method that puts some value(obtained from an excel file) into a hashmap with an array as the key

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}>

this method work for putting the values into the hashmap but i cannot seem to get any value from the hashmap when i try to call it there is always a 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);
    }

this is a sample of the file im reading the data from:

SBS

How can i get the hashmap to return me the value i want?

3
  • 2
    An array if only ever equal to itself. Don't use an array as your key. You could use a List, but that would still be very unclear. Why not define your own class, wit preperly named and types properties (and proper equals() and hashCode() methods, of course)? Commented Apr 30, 2017 at 9:30
  • 2
    Also, don't, ever, modify a key after it's been stored as a key in the map. That will break the map. Again, use a well-defined class, and make it immutable: map.put(new MyKey(dataParts[0], dataParts[1]), stopsData) Commented Apr 30, 2017 at 9:32
  • What did you find when you googled "Using array as key for hashmap java"? Commented Apr 30, 2017 at 9:44

2 Answers 2

3

Arrays are not suitable as keys in HashMaps, since arrays don't override Object's equals and hashCode methods (which means two different array instances containing the exact same elements will be considered as different keys by HashMap).

The alternatives are to use a List<String> instead of String[] as the key of the HashMap, or to use a TreeMap<String[]> with a custom Comparator<String[]> passed to the constructor.

Sign up to request clarification or add additional context in comments.

13 Comments

i edited the code above to use a List<String> but is still not able to get a value
@LimJunWei A List is an ordered Collection. Are the values in the List you put() in the HashMap appearing in the same order as the values in the List you try to get() from the HashMap? If you want the order to be ignored, you can use a Set<String> as the key. Note that if you modify the key after you put it in the Map, get won't work.
i checked and the values are in the same order and i did not modify the key as they key is directly read from the excel file but it still does not work
@LimJunWei I suggest you System.out.println the map and see if it contains what you think it does.
it contains some machine language that i cant understand
|
0

If you are having fixed array size then the example I'm posting might be useful. Here I've created two Object one is Food and Next is Product. Here Food object is use and added method to get string array.

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;
   }    
}

Food Model Class: Use as a Object instead of String[] and achieve String[] functionality.

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);
    }
}

Using HashMap example

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;
}

Using TreeMap example

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;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.