我目前以HTML格式提供以下数据:
Year| car type | # of cars sold
2001| Toyota-Camry | 242435
2000| Honda-Accord | 344423
2001| Honda-Accord | 555255
2000| Honda-Civic | 342344
2008| Toyota-Prius | 666154
1996| Honda-Accord | 114526
2001| Toyota-Prius | 90234
为了检索这些数据,我有一个BufferedReader
来读取HTML中的行。在数据出现之前,我在开头跳过几行,因为有空格。所以我的代码目前是
public class carSales {
private Map<Integer, HashMap<Integer, String>> carSalesMan =
new HashMap <Integer, HashMap<Integer, String>>;
private void getcarTypes(String url) {
try {
URL urlz = new URL(url);
URLConnection urlc = myURL.openConnection();
BufferedReader line = new BufferedReader
(new InputStreamReader(urlConnection.getInputStream()));
String next;
next = line.readLine();
while (next.contains("</s>") {
String[] parts = next.split(" ");
if (carSalesMan.isEmpty() || carSalesMan.get(Integer.parseInt(parts[0])) == null {
carSalesMan.put(Integer.parseInt(parts[0], new HashMap<Integer, String>());
carSalesMan.get(Integer.parseInt(parts[0])).put(Integer.parseInt(parts[2]), parts[1])
}
}
catch (IOException e) {
}
}
这个问题是它似乎只存储具有独特年份的数据。因此我的carSalesMan
变量的大小将为4,因为我只有4个唯一年份,当列表中断时它们会相互覆盖。是否有一种简单的方法可以添加所有类型的汽车,即使它在同一年?
答案 0 :(得分:3)
由于您的if语句,只有一个项目:
if (carSalesMan.isEmpty() || carSalesMan.get(Integer.parseInt(parts[0])) == null {
您有两种选择,如果您想为每个项目设置不同的插槽,则需要选择@JacobG。回答或者你可以删除这个if语句和用户一个存储项目集合的地图类型作为它的值。你有两种方法可以做第二种选择:
我相信你想要一个MultiValueMap而不是HashMap,它的工作方式几乎与HashMap完全相同,只不过它将值存储在每个键的集合中,而不是每个键只存储一个值。
它不是官方Java,但它是开源的。 您可以在这里找到文档:
或者,您可以使用扩展HashMap<K, V>
的自定义类自行实现它,该类包含HashMap<K, Collecton<V>>
答案 1 :(得分:1)
您在此尝试实现的是使用两个单独的键来存储值。使用诸如Guava之类的外部库,这相当于Table<Integer, Integer, String>
。如果你不想使用任何外部库,那么在这种情况下使用Map<Integer, Map<Integer, String>>
是一个非常好的对象。
您当前代码的问题在于,Map
为空或不包含特定年份时,它只会添加信息。您可以将其更改为以下内容,它可以正常工作:
public class carSales {
private Map<Integer, Map<Integer, String>> carSalesMan = new HashMap<>();
private void getcarTypes(String url) {
try {
URL urlz = new URL(url);
URLConnection urlc = urlz.openConnection();
BufferedReader line = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String next = line.readLine();
while (next.contains("</s>") {
String[] parts = next.split(" ");
int year = Integer.parseInt(parts[0]);
int amountSold = Integer.parseInt(parts[2]);
String model = parts[1];
carSalesMan.putIfAbsent(year, new HashMap<>());
carSalesMan.get(year).put(amountSold, model);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
请记住关闭您的连接/阅读器以防止内存泄漏!
编辑:如果您想使用Guava的Table
ADT,您可以使用以下内容:
public class carSales {
private Table<Integer, Integer, String> carSalesMan = HashBasedTable.create();
private void getcarTypes(String url) {
try {
URL urlz = new URL(url);
URLConnection urlc = urlz.openConnection();
BufferedReader line = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String next = line.readLine();
while (next.contains("</s>") {
String[] parts = next.split(" ");
int year = Integer.parseInt(parts[0]);
int amountSold = Integer.parseInt(parts[2]);
String model = parts[1];
carSalesMan.put(year, amountSold, model);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
答案 2 :(得分:0)
您好我会深入研究Java的库:
&#34; Java Collections Framework没有包含多重映射的界面,因为它们并没有被普遍使用。使用Map的值为List实例的多重映射是一个相当简单的问题。&#34;
来源:https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html