How to read a properties file in java in the origi

2019-02-01 23:42发布

This question already has an answer here:

I need to read a properties file and generate a Properties class in Java. I do so by using:

Properties props = new Properties();
props.load(new FileInputStream(args[0]));
for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
}

However, the properties returned by props.propertyName is not in the order of the original properties file. I understand that Properties are just old fashioned, non-generified Hashtables. I'm looking for a work around. Any idea? Thank you!

9条回答
劫难
2楼-- · 2019-02-01 23:45

Similar to one of the above, but w/out the overhead of maintaining our own list of values. All we have to do is maintain a separate ordered list of the keys, and provide a new "keys()" method.


public class SequencedProperties extends Properties {

    private static final long serialVersionUID = -7032434592318855760L;

    private List keyList = new ArrayList();

    @Override
    public synchronized Enumeration keys() {
        return Collections.enumeration(keyList);
    }

    @Override
    public synchronized Object put(Object key, Object value) {
        if (! containsKey(key)) {
            keyList.add(key);
        }

        return super.put(key, value);
    }

    @Override
    public synchronized Object remove(Object key) {
        keyList.remove(key);

        return super.remove(key);
    }

    @Override
    public synchronized void putAll(Map values) {
        for (Object key : values.keySet()) {
            if (! containsKey(key)) {
                keyList.add(key);
            }
        }

        super.putAll(values);
    }
}
查看更多
够拽才男人
3楼-- · 2019-02-01 23:46

To solve the problem: "to execute classes based on the order in the properties file." I normally used one of 2 possibilities:

1 - use one property as a comma-separated list with the class-names or with the keys to the class definition

loadClasses = class-definition-A, class-definition-B, class-definition-C

or (useful if the "definition" consists of more than one property)

loadClasses = keyA, keyB, keyC
keyA = class-definition-A
keyB = class-definition-B
keyC = class-definition-C


2 - use a key followed by an index (counter). Read the keys in a loop until no value is found.

class1 = class-definition-A
class2 = class-definition-B
class3 = class-definition-C

查看更多
Evening l夕情丶
4楼-- · 2019-02-01 23:49

You can extend Properties and delegate all map methods to a LinkedHashMap to retain the order. Here is an example (you may need to override some more methods):

public class LinkedProperties extends Properties{


    private static final long serialVersionUID = 1L;

    private Map<Object, Object> linkMap = new LinkedHashMap<Object,Object>();

    @Override
    public synchronized Object put(Object key, Object value){
        return linkMap.put(key, value);
    }

    @Override
    public synchronized boolean contains(Object value){
        return linkMap.containsValue(value);
    }

    @Override
    public boolean containsValue(Object value){
        return linkMap.containsValue(value);
    }

    @Override
    public synchronized Enumeration<Object> elements(){
        throw new UnsupportedOperationException(
          "Enumerations are so old-school, don't use them, "
        + "use keySet() or entrySet() instead");
    }

    @Override
    public Set<Entry<Object, Object>> entrySet(){
        return linkMap.entrySet();
    }

    @Override
    public synchronized void clear(){
        linkMap.clear();
    }

    @Override
    public synchronized boolean containsKey(Object key){
        return linkMap.containsKey(key);
    }

}
查看更多
可以哭但决不认输i
5楼-- · 2019-02-01 23:49

The fact they are represented as a Hashtable under the hood means that their order is not kept in any fashion.

I'd suggest you "roll your own" properties reader if you're absolutely desperate for this functionality.

查看更多
不美不萌又怎样
6楼-- · 2019-02-01 23:49

Proper implementation of keySet:

public class OrderedProperties extends Properties {

  private Set<Object> keySet = new LinkedHashSet<Object>(100);

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

  @Override
  public Set<Object> keySet() {
    return keySet;
  }

  @Override
  public synchronized Object put(Object key, Object value) {
    if (! keySet.contains(key)) {
        keySet.add(key);
    }
    return super.put(key, value);
  }

  @Override
  public synchronized Object remove(Object key) {
    keySet.remove(key);
    return super.remove(key);
  }

  @Override
  public synchronized void putAll(Map values) {
    for (Object key : values.keySet()) {
        if (! containsKey(key)) {
            keySet.add(key);
        }
    }
    super.putAll(values);
  }
}
查看更多
SAY GOODBYE
7楼-- · 2019-02-01 23:54

You may want to implement your own Properties class with similar functionalities. It will not be possible for you to obtain the order since, as you already pointed out, it uses Hashtable.

查看更多
登录 后发表回答