Search code examples
javaini4j

Read multiple values from an ini file, preserving order


I have the following Ini-File

[Test]
a=1
b=2
a=3

and I need these key value pairs in the correct order. My problem is, I can find no way to achieve this. I tried the following three options:

Ini ini = new Ini(new File("test.ini"));

for (String sectionName : ini.keySet()) {

        Section section = ini.get(sectionName);

    //run through keyset
        for (String key : section.keySet()) {
            System.out.println(key + " = " + section.get(key));

        }

        System.out.println();

    //run through all values
        for (String key : section.keySet()) {

            List<String> list = section.getAll(key);
            for (String value : list) {

                System.out.println(key + " = " + value);

            }
        }

        System.out.println();

    //run through entries
        Set<Entry<String,String>> se = section.entrySet();
        for(Entry<String,String> e:se){

            System.out.println(e.getKey() + " = " + e.getValue());

        }
}

but what I get is:

a = 3
b = 2

a = 1
a = 3
b = 2

b = 2
a = 3

None of this is in the correct Order or contains all values :(

//EDIT: Correct order should be like the ini-File:

a=1
b=2
a=3

Solution

  • I think your problem is that Section is implement as a Map an thus its iteration order dependent of its keys hashes and reallocation policies.

    Edit:

    I have downloaded ini4j source code and found that Section is deffined as:

    interface Section extends OptionMap
    {
        Section getChild(String key);
    
        String getName();
    
        Section getParent();
    
        String getSimpleName();
    
        Section addChild(String key);
    
        String[] childrenNames();
    
        Section lookup(String... path);
    
        void removeChild(String key);
    }
    

    Extending OptionMap interface which extends MultiMap interface:

    public interface OptionMap extends MultiMap<String, String>, CommentedMap<String, String>
    

    I found at BasicProfile implementation that the MultiMap implementation used by Ini class (the one retuned by ini.get(sectionName)) is an extension of CommonMultimap class which store its elements in a java.util.SortedMap. That means your keys will be ordered but not with the same order they appear in your file but the one given by java.util.SortedMap.

    At Oracle documentation site you can read that:

    public interface SortedMap<K,V> extends Map<K,V>
    

    Is:

    A Map that further provides a total ordering on its keys. The map is ordered according to the natural ordering of its keys, or by a Comparator typically provided at sorted map creation time. This order is reflected when iterating over the sorted map's collection views (returned by the entrySet, keySet and values methods). Several additional operations are provided to take advantage of the ordering. (This interface is the map analogue of SortedSet.)

    Conclusion:

    The ini file keys-at-same-level order information is lost in the file objects representation so unless you open the config file as a text file and load a list of key orders you won't be able to reproduce it.