4

How can I save this kind of map to file? (it should work for an android device too)

I tried:

        Properties properties = new Properties();

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

        try {
            properties.store(new FileOutputStream(context.getFilesDir() + MainActivity.FileName), null);
        } catch (IOException e) {
            e.printStackTrace();
        }

And I get:

class java.util.ArrayList cannot be cast to class java.lang.String (java.util.ArrayList and java.lang.String are in module java.base of loader 'bootstrap')

What should I do?

Ziv Sion
  • 424
  • 4
  • 14

1 Answers1

0

I was writing an answer based on String values serialization when I realized for your error that perhaps some value can be an ArrayList... I honestly don't fully understand the reasoning behind the error (of course, it is a cast, but I don't understand the java.util.ArrayList part)...

In any case, the problem is happening when you try storing your properties and it tries to convert your Object[] to String for saving.

In my original answer I suggested you to manually join your values when generating your file. It is straightforward with the join method of the String class:

Properties properties = new Properties();

for (String key : map.keySet()) {
  Object[] values = map.get(key);
  // Perform null checking
  String value = String.join(",", values);
  properties.put(key, value);
}

try {
  properties.store(new FileOutputStream(context.getFilesDir() + MainActivity.FileName), null);
} catch (IOException e) {
  e.printStackTrace();
}

For reading your values, you can use split:

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

InputStream in = null;
try {
  in = new FileInputStream(context.getFilesDir() + MainActivity.FileName);
  properties.load(in);

  for (String key : properties.stringPropertyNames()) {
    String value = properties.getProperty(k);
    // Perform null checking
    String[] values = value.split(",");
    map.put(key, value);
  }
} catch (Throwable t) {
  t.printStackTrace();
} finally {
  if (in != null) {
    try {
      in.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

But I think you have a much better approach: please, just use the Java builtin serialization mechanisms to save and restore your information.

For saving your map use ObjectOutputStream:

try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(context.getFilesDir() + MainActivity.FileName))){
  oos.writeObject(map);
}

You can read your map back as follows:

Map<String, Object> map;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(context.getFilesDir() + MainActivity.FileName))){
  map = (Map)ois.readObject();
}

If all the objects stored in your map are Serializables this second approach is far more flexible and it is not limited to String values like the first one.

jccampanero
  • 50,989
  • 3
  • 20
  • 49