背景
通过Properties.load(xxx)
的方式加载xxx.properties
文件时,再遍历输出时,不是按照文件中key
的配置顺序输出的。原因是Properties
类继承了无序的Hashtable
类。
解决
注:网上很多文章都进行了类似的分析,并给出了一些解决方式,典型的办法是写一个继承于原
Properties
的自定义类,并对一些方法进行重写。本文出现的原因,并不是有更高级的做法,只是一个补充,补充原因:我们知道Properties
遍历时,可以使用keys()
、stringPropertyNames()
、keySet()
、entrySet()
、propertyNames()
,而网上很多文章抄来抄去,我并没有发现完全覆盖这几个方法的版本,因此,以下贴出我的版本。
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* 遍历读取时,按照 properties 文件中 key 的顺序输出。
*
* @see <a href="https://www.jianshu.com/u/c6136e3324e5">简书主页</a>
*/
public class OrderedProperties extends Properties {
private static final long serialVersionUID = 6436282644356929955L;
private final LinkedHashSet<Object> keys = new LinkedHashSet<>();
public OrderedProperties() {
}
@Override
public Object put(Object key, Object value) {
keys.add(key);
return super.put(key, value);
}
@Override
public Enumeration<Object> keys() {
return Collections.enumeration(keys);
}
@Override
public Set<Object> keySet() {
return keys;
}
@Override
public Set<String> stringPropertyNames() {
Set<String> set = new LinkedHashSet<>();
for (Object key : this.keys) {
set.add(key.toString());
}
return set;
}
@Override
public Set<Map.Entry<Object, Object>> entrySet() {
Set<Map.Entry<Object, Object>> entrySet = new LinkedHashSet<>();
for (Object key : keys) {
entrySet.add(getEntryByKey(key, super.entrySet()));
}
return entrySet;
}
private Map.Entry<Object, Object> getEntryByKey(Object key, Set<Map.Entry<Object, Object>> entrySet) {
for (Map.Entry<Object, Object> entry : entrySet) {
if (entry.getKey().equals(key)) {
return entry;
}
}
return null;
}
@Override
public Enumeration<?> propertyNames() {
return Collections.enumeration(keys);
}
}