1

我有一些这样的Java代码:

Map<Map<String,String>,String> map = new HashMap<>();
int i = 0;
try (BufferedReader br = new BufferedReader(new FileReader("properties.txt")))
{

        String sCurrentLine;
        while ((sCurrentLine = br.readLine()) != null) {
                i++;
                String[] parts = sCurrentLine.split(",");
                System.out.println(parts[2]);
                Map<String,String> tempMap = new HashMap<>();
                tempMap.put("issuing_bank",parts[1]);
                tempMap.put("card_switch",parts[2]);
                tempMap.put("card_Type",parts[3]);
                map.put(tempMap,parts[0]);
        }

} catch (IOException e) {
        e.printStackTrace();
}

map我只包含12从我的文本文件中存储的第一个元素,这看起来很奇怪。出于调试目的,我使用了变量i并将其打印出来,即打印 的值22,这是我的文本文件中的确切计数。

我的文本文件如下所示:

447747,ICCI,Visa,Credit
421323,ICCI,Visa,Debit
421630,ICCI,Visa,Debit
455451,ICCI,Visa,Debit
469375,ICCI,Visa,Debit
523951,ICCI,MasterCard,Credit
5399,ICCI,MasterCard,Debit
517652,HDFC,MasterCard,Credit
558818,HDFC,MasterCard,Credit 
512622,SBI,MasterCard,Credit
526468,SBI,MasterCard,Credit
400975,Citi,Visa,Credit
402856,Citi,Visa,Credit
461726,Citi,Visa,Credit
552004,Citi,MasterCard,Debit
468805,Axis,Visa,Debit
418157,ICCI,Visa,Debit
524133,Citi,MasterCard,Credit
528945,HDFC,MasterCard,Credit
437748,SBI,MasterCard,Credit
524111,HDFC,MasterCard,Credit
431757,SBI,Visa,Credit

我很困惑,为什么只有12元素被读入我的map. 我在这里错过了什么吗?

提前致谢。

4

5 回答 5

5

解决方案很简单:您在这一行中有错误的参数顺序:

map.put(tempMap,parts[0]);

它应该说

map.put(parts[0],tempMap);

您必须相应地更改变量声明的类型参数。你在哪里

Map<Map<String,String>,String> map = new HashMap<>();

你必须把

Map<String,Map<String,String>> map = new HashMap<>();

总而言之,在这些更改之后,我相信您将拥有您真正想要的结构:从parts[0]地图到其余记录字段的地图。

我应该补充一点,您的解决方案(除了您的 nick :) 让您成为主要使用 Groovy 等动态语言编写代码的开发人员;这种风格不适合 Java 的语言特性。在 Java 中,你最好定义一个专门的 bean 类:

public class CardHolder {
  public final String cardNumber, issuingBank, cardSwitch, cardType;

  public CardHolder(String[] record) {
    int i = 0;
    cardNumber = record[i++];
    issuingBank = record[i++];
    cardSwitch = record[i++];
    cardType = record[i++];
  }
}

首先,这种方法更好,因为您的阅读循环变得更简单,更重要:

while ((sCurrentLine = br.readLine()) != null) {
  final CardHolder ch = new CardHolder(sCurrentLine.split(","));
  map.put(ch.cardNumber, ch);
}

此外,这将使您可以更好地控制记录的其他方面;例如一个很好的习惯toString和类似的。另请注意,这几乎没有导致更多代码:它只是通过关注点分离原则进行了重组。

(最后的一个小观察:在 Java 中,字符串变量的 s 前缀是不习惯的,因为它在静态类型语言中是多余的;请放心,您永远不会遇到 Java 中的错误,因为在 String 所在的位置发生 Integer预期的。)

于 2012-10-10T12:43:04.673 回答
2

您应该更改创建地图的方式..代替以下声明:-

Map<Map<String,String>,String> map = new HashMap<>();

而不是这个,你应该有一个: -

Map<String, Map<String,String>> map = new HashMap<>();

您应该始终将不可变类型作为 Map 中的键。

此更改之后,您应该更改:-

map.put(tempMap,parts[0]);

到: -

map.put(parts[0], tempMap);
于 2012-10-10T12:44:59.520 回答
1

我认为你有论据

map.put(tempMap,parts[0]);

逆转。您正在将 tempMap 映射到数字,您可能希望将数字映射到 tempMap:

map.put(parts[0], tempMap);

使用

Map<String, Map<String,String>> map = new HashMap<>();
于 2012-10-10T12:44:04.947 回答
1

您应该使用 Map 作为值,因为HashMap 相等性基于它具有的键值对。.

map.put(parts[0],tempMap);

下面的一个简单程序将说明这一事实

    Map<String, String> tempMap1 = new HashMap<String, String>();
    tempMap1.put("issuing_bank", "ICICI");
    tempMap1.put("card_switch", "Visa");
    tempMap1.put("card_Type", "Debit");

    Map<String, String> tempMap2 = new HashMap<String, String>();

    tempMap2.put("issuing_bank", "ICICI");
    tempMap2.put("card_switch", "Visa");
    tempMap2.put("card_Type", "Debit");

    System.out.println(tempMap1.equals(tempMap2));//Prints true

输出:

true

所以你的声明应该如下所示。请记住,您应该始终使用不可变对象作为 HashMap 中的键。

Map<String,Map<String,String>> map = new HashMap<String,Map<String,String>>();
于 2012-10-10T12:44:32.910 回答
-1

那是因为您使用地图(tempMap)作为键。这是错误的。

于 2012-10-10T12:42:16.590 回答