通过 while 循环在 hashmap 中添加 <Key, Value> 但不起作用
Adding <Key, Value> in hashmap by while loop but not working
我有以下 CSV 文件,我想创建一个 hashmap,其中唯一键应该是每一行的第一个值,值应该是一个 arraylist
,其中包含第一行下每一行的信息这一行的价值。 CSV 示例如下:
1,0
1,1
1,2
1,3
1,4
2,0
2,1
2,2
4,0
10,0
10,1
10,2
10,3
10,4
10,5
理想情况下,我希望最终的 ArrayList 类似于:
{1=[1,0, 1,1, 1,2, 1,3, 1,4], 2=[2,0, 2,1, 2,2], 4=[4,0], 10=[10,0, 10,1, 10,2, 10,3, 10,4, 10, 5]}
下面是我用来尝试通过 while 循环解决这个问题的代码
public static void main(String[] args) {
int activityRecord = 1;
String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv";
HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>();
try {
BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile));
String agentActivity = null;
ArrayList activities = new ArrayList();
while ((agentActivity = activityReader.readLine()) != null){
String activityWithAllInfo = agentActivity;
String[] activitySpilted = agentActivity.split(",");
int activityAgentID = Integer.parseInt(activitySpilted[0]);
if (activityAgentID == activityRecord){
activities.add(activityWithAllInfo);
} else if (activityAgentID != activityRecord){
idAndAllActivities.put(activityRecord, activities);
activityRecord = activityAgentID;
activities.clear();
activities.add(activityWithAllInfo);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
}
基本上,我尝试证明是否activityAgentID == activityRecord
(最初为1),如果不同,我会将添加到hashmap并清除activities
arrayList .然而,这个程序的输出是这样的:
{1=[10,0, 10,1, 10,2, 10,3, 10,4, 10,5], 2=[10,0, 10,1, 10,2, 10,3, 10,4, 10,5], 4=[10,0, 10,1, 10,2, 10,3, 10,4, 10,5]}
这不是我想要的,我尝试调试它,但我找不到原因,因为我对 Java 真的很陌生......我想知道你是否知道如何解决这个问题?任何提示将不胜感激!
谢谢!
您的代码中的问题是您重用了 activities
数组。活动数组和 HashMap
中分配的数组都指向相同的引用,因此如果更新 activities
数组,地图中的所有条目也将更新。
假设文件中的密钥已排序,您可以像这样稍微调整一下代码
HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>();
try {
BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile));
String agentActivity = null;
ArrayList<String> activities = new ArrayList<>();
while ((agentActivity = activityReader.readLine()) != null){
String[] activitySpilted = agentActivity.split(",");
int activityAgentID = Integer.parseInt(activitySpilted[0]);
if (activityAgentID == activityRecord){
activities.add(agentActivity);
} else {
idAndAllActivities.put(activityRecord, activities);
activityRecord = activityAgentID;
activities = new ArrayList<>();
activities.add(agentActivity);
}
}
idAndAllActivities.put(activityRecord, activities);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
请注意,您不需要这个:String activityWithAllInfo = agentActivity;
因为 String
在 Java
中是不可变的
你可以换一种方式。如果 CSV 文件的顺序更改如下,则不会中断的方法如下:
1,0
1,1
2,0
1,2
10,0
10,1
10,2
1,3
1,4
2,1
2,2
4,0
10,3
10,4
10,5
使用此 CSV,您的代码将失败,因为您依赖 CSV 文件将所有 1
activity 记录放在一起。为了解决这个问题,请尝试以下操作(注意您不再依赖 activityRecord
):
public static void main(String[] args) {
String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv";
HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>();
try {
BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile));
String agentActivity = null;
while ((agentActivity = activityReader.readLine()) != null){
String activityWithAllInfo = agentActivity;
String[] activitySpilted = agentActivity.split(",");
int activityAgentID = Integer.parseInt(activitySpilted[0]);
if (idAndAllActivities.containsKey(activityAgentID)){
ArrayList existentActivities = idAndAllActivities.get(activityAgentID);
existentActivities.add(activityWithAllInfo);
} else {
ArrayList activities = new ArrayList();
activities.add(activityWithAllInfo);
idAndAllActivities.put(activityAgentID, activities);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
}
假设您使用的是 Java 8 或更高版本,在 Files.lines
和 Collectors.groupingBy
的帮助下可以大大简化任务并使代码更具可读性:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv";
Map<Integer,List<String>> idAndAllActivities = null;
try (Stream<String> content = Files.lines(Paths.get(activitiesFile))) {
idAndAllActivities = content.collect(Collectors.groupingBy(row -> Integer.parseInt(row.split(",")[0])));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
}
}
我有以下 CSV 文件,我想创建一个 hashmap,其中唯一键应该是每一行的第一个值,值应该是一个 arraylist
,其中包含第一行下每一行的信息这一行的价值。 CSV 示例如下:
1,0
1,1
1,2
1,3
1,4
2,0
2,1
2,2
4,0
10,0
10,1
10,2
10,3
10,4
10,5
理想情况下,我希望最终的 ArrayList 类似于:
{1=[1,0, 1,1, 1,2, 1,3, 1,4], 2=[2,0, 2,1, 2,2], 4=[4,0], 10=[10,0, 10,1, 10,2, 10,3, 10,4, 10, 5]}
下面是我用来尝试通过 while 循环解决这个问题的代码
public static void main(String[] args) {
int activityRecord = 1;
String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv";
HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>();
try {
BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile));
String agentActivity = null;
ArrayList activities = new ArrayList();
while ((agentActivity = activityReader.readLine()) != null){
String activityWithAllInfo = agentActivity;
String[] activitySpilted = agentActivity.split(",");
int activityAgentID = Integer.parseInt(activitySpilted[0]);
if (activityAgentID == activityRecord){
activities.add(activityWithAllInfo);
} else if (activityAgentID != activityRecord){
idAndAllActivities.put(activityRecord, activities);
activityRecord = activityAgentID;
activities.clear();
activities.add(activityWithAllInfo);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
}
基本上,我尝试证明是否activityAgentID == activityRecord
(最初为1),如果不同,我会将activities
arrayList .然而,这个程序的输出是这样的:
{1=[10,0, 10,1, 10,2, 10,3, 10,4, 10,5], 2=[10,0, 10,1, 10,2, 10,3, 10,4, 10,5], 4=[10,0, 10,1, 10,2, 10,3, 10,4, 10,5]}
这不是我想要的,我尝试调试它,但我找不到原因,因为我对 Java 真的很陌生......我想知道你是否知道如何解决这个问题?任何提示将不胜感激!
谢谢!
您的代码中的问题是您重用了 activities
数组。活动数组和 HashMap
中分配的数组都指向相同的引用,因此如果更新 activities
数组,地图中的所有条目也将更新。
假设文件中的密钥已排序,您可以像这样稍微调整一下代码
HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>();
try {
BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile));
String agentActivity = null;
ArrayList<String> activities = new ArrayList<>();
while ((agentActivity = activityReader.readLine()) != null){
String[] activitySpilted = agentActivity.split(",");
int activityAgentID = Integer.parseInt(activitySpilted[0]);
if (activityAgentID == activityRecord){
activities.add(agentActivity);
} else {
idAndAllActivities.put(activityRecord, activities);
activityRecord = activityAgentID;
activities = new ArrayList<>();
activities.add(agentActivity);
}
}
idAndAllActivities.put(activityRecord, activities);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
请注意,您不需要这个:String activityWithAllInfo = agentActivity;
因为 String
在 Java
你可以换一种方式。如果 CSV 文件的顺序更改如下,则不会中断的方法如下:
1,0
1,1
2,0
1,2
10,0
10,1
10,2
1,3
1,4
2,1
2,2
4,0
10,3
10,4
10,5
使用此 CSV,您的代码将失败,因为您依赖 CSV 文件将所有 1
activity 记录放在一起。为了解决这个问题,请尝试以下操作(注意您不再依赖 activityRecord
):
public static void main(String[] args) {
String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv";
HashMap<Integer, ArrayList<String>> idAndAllActivities = new HashMap<>();
try {
BufferedReader activityReader = new BufferedReader(new FileReader(activitiesFile));
String agentActivity = null;
while ((agentActivity = activityReader.readLine()) != null){
String activityWithAllInfo = agentActivity;
String[] activitySpilted = agentActivity.split(",");
int activityAgentID = Integer.parseInt(activitySpilted[0]);
if (idAndAllActivities.containsKey(activityAgentID)){
ArrayList existentActivities = idAndAllActivities.get(activityAgentID);
existentActivities.add(activityWithAllInfo);
} else {
ArrayList activities = new ArrayList();
activities.add(activityWithAllInfo);
idAndAllActivities.put(activityAgentID, activities);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
}
假设您使用的是 Java 8 或更高版本,在 Files.lines
和 Collectors.groupingBy
的帮助下可以大大简化任务并使代码更具可读性:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Example {
public static void main(String[] args) {
String activitiesFile = "scenarios/BrusselsPopulationFromR/BrusselsActivities.csv";
Map<Integer,List<String>> idAndAllActivities = null;
try (Stream<String> content = Files.lines(Paths.get(activitiesFile))) {
idAndAllActivities = content.collect(Collectors.groupingBy(row -> Integer.parseInt(row.split(",")[0])));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(idAndAllActivities);
}
}