简体   繁体   中英

Android studio store map<String, Integer> in file.properties with properties

I'm trying to save file.properties. I can save a <String, String> map.

But when I try to save a <String, Integer> map I get an error.

Is there a way to save a <String, Integer> map?

The code that does not work:

    Map<String, Integer> int_map = new HashMap<String, Integer>();
    int_map.put("Red", 4);
    int_map.put("Orange-red", 3);
    int_map.put("Orange", 2);
    int_map.put("Green", 1);
    int_map.put("Blue", 0);

    Properties properties = new Properties(); // Crate properties object to store the data

    for (Map.Entry<String, Integer> entry : int_map.entrySet()) {
        properties.put(entry.getKey(), entry.getValue());
    }

    try {
        properties.store(new FileOutputStream(this.getFilesDir() + "data.properties"), null);
    } catch (IOException e) {
        e.printStackTrace();
    }

The code that works:

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

        map.put("hello", "world");
        
        Properties properties = new Properties(); // Crate properties object to store the data

        for (Map.Entry<String, String> entry : map.entrySet()) {
            properties.put(entry.getKey(), entry.getValue());
        }

        try {
            properties.store(new FileOutputStream(this.getFilesDir() + "data.properties"), null);
        } catch (IOException e) {
            e.printStackTrace();
        }

The error that I get when I try to run it:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.trialanderror, PID: 24139
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.trialanderror/com.example.trialanderror.MainActivity}: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3555)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8016)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1087)
     Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        at java.util.Properties.store0(Properties.java:836)
        at java.util.Properties.store(Properties.java:820)
        at com.example.trialanderror.MainActivity.onCreate(MainActivity.java:36)
        at android.app.Activity.performCreate(Activity.java:7957)
        at android.app.Activity.performCreate(Activity.java:7946)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3530)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:8016) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1087) 

It is by design.

From documentation we can read:

Because Properties inherits from Hashtable , the put and putAll methods can be applied to a Properties object. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not Strings . The setProperty method should be used instead. If the store or save method is called on a "compromised" Properties object that contains a non-String key or value, the call will fail.

(emphasis mine).

In other words you need to only store String objects for keys and values. If you have Integer, convert it to String and then write it to Properties. In your case instead of

properties.put(entry.getKey(), entry.getValue());

you may want to use something like

properties.setProperty(entry.getKey(), entry.getValue().toString());
//        |                                            ^-- convert Integer to String
//        |
//        ^--use `setProperty(String key, String value)` method instead of
//           `put(K key, V value)` to let compiler enforce String as key and value

OR if map can contain null value and instead of getting NPE you want to store it as String "null" use Objects.toString(entry.getValue()) instead of entry.getValue().toString() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM