Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

dictionary - Java Map with ArrayList weirdness

I need another pair of eyes, because I am missing something. This is my code: ...

    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( "
Read: " + 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( "
sub 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( "
Final 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 );
            }
        }
    }

... I am using Windows and it compiles without a problem. & 'C:Program Filesjavajdk1.8.0_271injavac' -Xlint:unchecked .TestMap.java The input file is:

    Replace, Title, Description, Language
    Create
    Delete
    Change, Title, Description**

The result I expect would be in the order of key, array of strings like:

    DELETE/[]
    CREATE/[]
    CHANGE/[TITLE,DESCRIPTION]
    REPLACE/[TITLE,DESCRIPTION,LANGUAGE]

The result I get (with debug print statements):

    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]

Why am I getting the same ArrayList for all keys?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Put ArrayList sub = new ArrayList<>(); inside the loop, you are updating the same array. That is causing the issue. If you notice you are using the same array and clearing the array also putting the same array reference inside the map value. so the map value will contain the last value of array for all keys.

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( "
Read: " + 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( "
sub 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( "
Final 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 );
            }
        }
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...