Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。
总有时候会有关心顺序一致的需求,恰如有 org.apache.commons.collections.OrderdMap(其实用 LinkedHashMap 就是保证顺序) 一样,我们也想要有个 OrderdProperties。网上查了下还真有:
http://livedocs.adobe.com/jrun/4/javadocs/jrunx/util/OrderedProperties.html
不过没找到源码,其实自己写一个 OrderedProperties 也不难,并不需要重头写起,只要继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 即可,其中用一个 LinkedHashSet 来保存它的所有 key。完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.mstar.investmeplugin; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.Properties; import java.util.Set; /** * OrderedProperties * @author Unmi * @date 2012-12-07 */ public class OrderedProperties extends Properties { private static final long serialVersionUID = -4627607243846121965L; private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>(); public Enumeration<Object> keys() { return Collections.<Object> enumeration(keys); } public Object put(Object key, Object value) { keys.add(key); return super.put(key, value); } public Set<Object> keySet() { return keys; } public Set<String> stringPropertyNames() { Set<String> set = new LinkedHashSet<String>(); for (Object key : this.keys) { set.add((String) key); } return set; } } |
用法:
1 2 3 4 |
Properties props = new OrderedProperties(); props.load(fileInputStream); //通过 keys(), keySet() 或 stringPropertyNames 来遍历都能保证按文件中的顺序输出 |
一直都是 StackOverflow 威武,本文主要参考自: http://stackoverflow.com/questions/1312383/pulling-values-from-a-java-properties-file-in-order
再看一个在 Playframework1 中的保持顺序的 OrderSafeProperties 的实现 https://github.com/playframework/play1/blob/master/framework/src/play/utils/OrderSafeProperties.java
本文链接 https://yanbin.blog/ordered-java-properties-class/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
答主,你还要覆盖HashTable的remove方法,否则删除Properties的时候会抛出异常。
是的,如果做的严格一些,需要考虑到所有 Hashtable 的方法调用。
赞