Java 地图与 ArrayList 怪异
Java Map with ArrayList weirdness
我需要另一双眼睛,因为我错过了一些东西。这是我的代码:
...
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.*;
import java.nio.file.*;
public class TestMap {
private Map<String, ArrayList<String>> validCommands = new HashMap<String, ArrayList<String>>();
public TestMap( ) throws Exception {
getCommands();
}
private void getCommands() throws Exception {
Map<String,ArrayList<String>> dataMap = new HashMap<>();
String nameFile = "." + File.separator + "TestMap.txt";
FileInputStream fis = new FileInputStream( nameFile );
Scanner input = new Scanner( fis );
ArrayList<String> sub = new ArrayList<>();
while(input.hasNext()) {
String[] tt = {""};
tt[0] = input.nextLine().replace( " ", "" ).toUpperCase();
// Debug next 1 line
System.out.println( "\nRead: " + tt[0] );
CharSequence divider = ",";
sub.clear();
if( tt[0].contains( divider ) ) {
tt = tt[0].split( ",", 2 );
// Debug next 2 lines
System.out.print( "Split to " );
for( int i = 0; i<tt.length; i++ ) System.out.print( tt[i] + "/" );
if( tt.length > 1 ) {
for( int i = 1; i<tt.length; i++ ) {
sub.add( tt[i] );
}
}
}
// Debug next 2 lines
System.out.println( "\nsub is now " + sub );
System.out.println( "Now putting " + tt[0] + sub );
dataMap.put( tt[0], sub );
}
input.close();
// Debug next 3 lines
System.out.println( "\nFinal result:" );
for( String s : dataMap.keySet() ) System.out.println( s + "/" + dataMap.get( s ) );
System.out.println();
}
public static void main( String[] args ) {
try {
TestMap testmap = new TestMap();
}
catch ( Exception e ) {
System.exit( 1 );
}
}
}
...
我正在使用 Windows 并且编译没有问题。
& 'C:\Program Files\java\jdk1.8.0_271\bin\javac' -Xlint:未检查。\TestMap.java
输入文件是:
Replace, Title, Description, Language
Create
Delete
Change, Title, Description**
我期望的结果是 key,字符串数组 的顺序,例如:
DELETE/[]
CREATE/[]
CHANGE/[TITLE,DESCRIPTION]
REPLACE/[TITLE,DESCRIPTION,LANGUAGE]
我得到的结果(带有调试打印语句):
java TestMap
Read: REPLACE,TITLE,DESCRIPTION,LANGUAGE
Split to REPLACE/TITLE,DESCRIPTION,LANGUAGE/
sub is now [TITLE,DESCRIPTION,LANGUAGE]
Now putting REPLACE[TITLE,DESCRIPTION,LANGUAGE]
Read: CREATE
sub is now []
Now putting CREATE[]
Read: DELETE
sub is now []
Now putting DELETE[]
Read: CHANGE,TITLE,DESCRIPTION
Split to CHANGE/TITLE,DESCRIPTION/
sub is now [TITLE,DESCRIPTION]
Now putting CHANGE[TITLE,DESCRIPTION]
Final result:
DELETE/[TITLE,DESCRIPTION]
CREATE/[TITLE,DESCRIPTION]
CHANGE/[TITLE,DESCRIPTION]
REPLACE/[TITLE,DESCRIPTION]
为什么我的所有键都得到相同的 ArrayList?
把ArrayList sub = new ArrayList<>();在循环内,您正在更新同一个数组。这就是导致问题的原因。如果您注意到您正在使用相同的数组并清除该数组,还会将相同的数组引用放入映射值中。因此映射值将包含所有键的数组的最后一个值。
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.*;
import java.nio.file.*;
public class TestMap {
private Map<String, ArrayList<String>> validCommands = new HashMap<String, ArrayList<String>>();
public TestMap( ) throws Exception {
getCommands();
}
private void getCommands() throws Exception {
Map<String,ArrayList<String>> dataMap = new HashMap<>();
String nameFile = "." + File.separator + "TestMap.txt";
FileInputStream fis = new FileInputStream( nameFile );
Scanner input = new Scanner( fis );
while(input.hasNext()) {
ArrayList<String> sub = new ArrayList<>();
String[] tt = {""};
tt[0] = input.nextLine().replace( " ", "" ).toUpperCase();
// Debug next 1 line
System.out.println( "\nRead: " + tt[0] );
CharSequence divider = ",";
if( tt[0].contains( divider ) ) {
tt = tt[0].split( ",", 2 );
// Debug next 2 lines
System.out.print( "Split to " );
for( int i = 0; i<tt.length; i++ ) System.out.print( tt[i] + "/" );
if( tt.length > 1 ) {
for( int i = 1; i<tt.length; i++ ) {
sub.add( tt[i] );
}
}
}
// Debug next 2 lines
System.out.println( "\nsub is now " + sub );
System.out.println( "Now putting " + tt[0] + sub );
dataMap.put( tt[0], sub );
}
input.close();
// Debug next 3 lines
System.out.println( "\nFinal result:" );
for( String s : dataMap.keySet() ) System.out.println( s + "/" + dataMap.get( s ) );
System.out.println();
}
public static void main( String[] args ) {
try {
TestMap testmap = new TestMap();
}
catch ( Exception e ) {
System.exit( 1 );
}
}
}
我需要另一双眼睛,因为我错过了一些东西。这是我的代码: ...
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.*;
import java.nio.file.*;
public class TestMap {
private Map<String, ArrayList<String>> validCommands = new HashMap<String, ArrayList<String>>();
public TestMap( ) throws Exception {
getCommands();
}
private void getCommands() throws Exception {
Map<String,ArrayList<String>> dataMap = new HashMap<>();
String nameFile = "." + File.separator + "TestMap.txt";
FileInputStream fis = new FileInputStream( nameFile );
Scanner input = new Scanner( fis );
ArrayList<String> sub = new ArrayList<>();
while(input.hasNext()) {
String[] tt = {""};
tt[0] = input.nextLine().replace( " ", "" ).toUpperCase();
// Debug next 1 line
System.out.println( "\nRead: " + tt[0] );
CharSequence divider = ",";
sub.clear();
if( tt[0].contains( divider ) ) {
tt = tt[0].split( ",", 2 );
// Debug next 2 lines
System.out.print( "Split to " );
for( int i = 0; i<tt.length; i++ ) System.out.print( tt[i] + "/" );
if( tt.length > 1 ) {
for( int i = 1; i<tt.length; i++ ) {
sub.add( tt[i] );
}
}
}
// Debug next 2 lines
System.out.println( "\nsub is now " + sub );
System.out.println( "Now putting " + tt[0] + sub );
dataMap.put( tt[0], sub );
}
input.close();
// Debug next 3 lines
System.out.println( "\nFinal result:" );
for( String s : dataMap.keySet() ) System.out.println( s + "/" + dataMap.get( s ) );
System.out.println();
}
public static void main( String[] args ) {
try {
TestMap testmap = new TestMap();
}
catch ( Exception e ) {
System.exit( 1 );
}
}
}
... 我正在使用 Windows 并且编译没有问题。 & 'C:\Program Files\java\jdk1.8.0_271\bin\javac' -Xlint:未检查。\TestMap.java 输入文件是:
Replace, Title, Description, Language
Create
Delete
Change, Title, Description**
我期望的结果是 key,字符串数组 的顺序,例如:
DELETE/[]
CREATE/[]
CHANGE/[TITLE,DESCRIPTION]
REPLACE/[TITLE,DESCRIPTION,LANGUAGE]
我得到的结果(带有调试打印语句):
java TestMap
Read: REPLACE,TITLE,DESCRIPTION,LANGUAGE
Split to REPLACE/TITLE,DESCRIPTION,LANGUAGE/
sub is now [TITLE,DESCRIPTION,LANGUAGE]
Now putting REPLACE[TITLE,DESCRIPTION,LANGUAGE]
Read: CREATE
sub is now []
Now putting CREATE[]
Read: DELETE
sub is now []
Now putting DELETE[]
Read: CHANGE,TITLE,DESCRIPTION
Split to CHANGE/TITLE,DESCRIPTION/
sub is now [TITLE,DESCRIPTION]
Now putting CHANGE[TITLE,DESCRIPTION]
Final result:
DELETE/[TITLE,DESCRIPTION]
CREATE/[TITLE,DESCRIPTION]
CHANGE/[TITLE,DESCRIPTION]
REPLACE/[TITLE,DESCRIPTION]
为什么我的所有键都得到相同的 ArrayList?
把ArrayList sub = new ArrayList<>();在循环内,您正在更新同一个数组。这就是导致问题的原因。如果您注意到您正在使用相同的数组并清除该数组,还会将相同的数组引用放入映射值中。因此映射值将包含所有键的数组的最后一个值。
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.*;
import java.nio.file.*;
public class TestMap {
private Map<String, ArrayList<String>> validCommands = new HashMap<String, ArrayList<String>>();
public TestMap( ) throws Exception {
getCommands();
}
private void getCommands() throws Exception {
Map<String,ArrayList<String>> dataMap = new HashMap<>();
String nameFile = "." + File.separator + "TestMap.txt";
FileInputStream fis = new FileInputStream( nameFile );
Scanner input = new Scanner( fis );
while(input.hasNext()) {
ArrayList<String> sub = new ArrayList<>();
String[] tt = {""};
tt[0] = input.nextLine().replace( " ", "" ).toUpperCase();
// Debug next 1 line
System.out.println( "\nRead: " + tt[0] );
CharSequence divider = ",";
if( tt[0].contains( divider ) ) {
tt = tt[0].split( ",", 2 );
// Debug next 2 lines
System.out.print( "Split to " );
for( int i = 0; i<tt.length; i++ ) System.out.print( tt[i] + "/" );
if( tt.length > 1 ) {
for( int i = 1; i<tt.length; i++ ) {
sub.add( tt[i] );
}
}
}
// Debug next 2 lines
System.out.println( "\nsub is now " + sub );
System.out.println( "Now putting " + tt[0] + sub );
dataMap.put( tt[0], sub );
}
input.close();
// Debug next 3 lines
System.out.println( "\nFinal result:" );
for( String s : dataMap.keySet() ) System.out.println( s + "/" + dataMap.get( s ) );
System.out.println();
}
public static void main( String[] args ) {
try {
TestMap testmap = new TestMap();
}
catch ( Exception e ) {
System.exit( 1 );
}
}
}