Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pulling values from a Java Properties file in order?

I have a properties file where the order of the values is important. I want to be able to iterate through the properties file and output the values based on the order of the original file.

However, since the Properties file is backed by, correct me if I'm wrong, a Map that does not maintain insertion order, the iterator returns the values in the wrong order.

Here is the code I'm using

Enumeration names = propfile.propertyNames();
while (names.hasMoreElements()) {
    String name = (String) names.nextElement();
    //do stuff
}

Is there anyway to get the Properties back in order short of writting my own custom file parser?

like image 240
James McMahon Avatar asked Aug 21 '09 14:08

James McMahon


4 Answers

Extend java.util.Properties, override both put() and keys():

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.HashMap;

public class LinkedProperties extends Properties {
    private final HashSet<Object> keys = new LinkedHashSet<Object>();

    public LinkedProperties() {
    }

    public Iterable<Object> orderedKeys() {
        return Collections.list(keys());
    }

    public Enumeration<Object> keys() {
        return Collections.<Object>enumeration(keys);
    }

    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }
}
like image 60
Dominique Laurent Avatar answered Nov 12 '22 09:11

Dominique Laurent


Nope - maps are inherently "unordered".

You could possibly create your own subclass of Properties which overrode setProperty and possibly put, but it would probably get very implementation-specific... Properties is a prime example of bad encapsulation. When I last wrote an extended version (about 10 years ago!) it ended up being hideous and definitely sensitive to the implementation details of Properties.

like image 42
Jon Skeet Avatar answered Nov 12 '22 10:11

Jon Skeet


If you can alter the property names your could prefix them with a numeral or other sortable prefix and then sort the Properties KeySet.

like image 7
Clint Avatar answered Nov 12 '22 10:11

Clint


Working example :

Map<String,String> properties = getOrderedProperties(new FileInputStream(new File("./a.properties")));
properties.entrySet().forEach(System.out::println);

Code for it

public Map<String, String> getOrderedProperties(InputStream in) throws IOException{
    Map<String, String> mp = new LinkedHashMap<>();
    (new Properties(){
        public synchronized Object put(Object key, Object value) {
            return mp.put((String) key, (String) value);
        }
    }).load(in);
    return mp;
}
like image 7
Dharmendrasinh Chudasama Avatar answered Nov 12 '22 11:11

Dharmendrasinh Chudasama