如何在java中对属性进行排序?
我有一个Properties变量,有时我需要添加其他属性。
Properties myBasicProps = this.getClass.getResourceAsStream(MY_PROPS_PATH); ... Properties otherProps = new Properties(); otherProps.load(new StringReader(tempPropsString)); //tempPropsString contains my temporary properties myBasicProps.putAll(otherProps);
我想在此之后对myBasicProps
进行排序。 我不想获取所有键和值,使用Collections.sort()
对它们进行排序,然后将它们全部放到新对象中。 有没有更好的办法?
不, java.util.Properties
扩展了java.util.Hashtable
,它没有为键或值定义可预测的排序顺序。
您可以尝试将所有值转储为类似java.util.TreeMap
,这将对您的密钥强加自然顺序。
你所要做的就是创建扩展属性的类。 来源: java2s.com
import java.io.FileOutputStream; import java.util.Collections; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; public class Main{ public static void main(String[] args) throws Exception { SortedProperties sp = new SortedProperties(); sp.put("B", "value B"); sp.put("C", "value C"); sp.put("A", "value A"); sp.put("D", "value D"); FileOutputStream fos = new FileOutputStream("sp.props"); sp.store(fos, "sorted props"); } } class SortedProperties extends Properties { public Enumeration keys() { Enumeration keysEnum = super.keys(); Vector keyList = new Vector (); while(keysEnum.hasMoreElements()){ keyList.add((String)keysEnum.nextElement()); } Collections.sort(keyList); return keyList.elements(); } }
这个对我有用。
@ danisupr4有最好的解决方案。
我会略微改进它,所以你不会在你的IDE中收到任何警告:
public static class MyProperties extends Properties { private static final long serialVersionUID = 1L; public Enumeration
TreeMap应该是最简单的方法:
Properties myProps = this.getClass.getResourceAsStream(MY_PROPS_PATH); try { myProps.load(new FileInputStream(extraPropertiesFilename)); //you can load more properties from external file Map sortedMap = new TreeMap(myProps); //output sorted properties (key=value) for (String key : sortedMap.keySet()) { System.out.println(key + "=" + sortedMap.get(key)); } } catch (Exception e) { e.printStackTrace(); }
覆盖keys
适用于Java 8 ,但是从Java 9开始 ,方法store
的新实现不再调用方法keys
而是调用方法entrySet
。
因此,您还必须覆盖entrySet
,以便在存储时使用Java 8/9/10对Properties
进行排序。
这是一个内联覆盖的示例:
Properties properties = new Properties() { private static final long serialVersionUID = 1L; @Override public Set keySet() { return Collections.unmodifiableSet(new TreeSet(super.keySet())); } @Override public Set> entrySet() { Set> set1 = super.entrySet(); Set> set2 = new LinkedHashSet>(set1.size()); Iterator> iterator = set1.stream().sorted(new Comparator>() { @Override public int compare(java.util.Map.Entry o1, java.util.Map.Entry o2) { return o1.getKey().toString().compareTo(o2.getKey().toString()); } }).iterator(); while (iterator.hasNext()) set2.add(iterator.next()); return set2; } @Override public synchronized Enumeration keys() { return Collections.enumeration(new TreeSet(super.keySet())); } };
只需对键进行排序就简单得多:
List keys = new ArrayList () for(String key : properties.stringPropertyNames()) { keys.add(key) } Collections.sort(keys);
你可以覆盖txt文件中保存排序属性的keys()方法:
//this method downloaded from edu.umd.cs.findbugs.config package @SuppressWarnings("unchecked") @Override public synchronized Enumeration keys() { Set> set = keySet(); return (Enumeration) sortKeys((Set) set); } static public Enumeration> sortKeys(Set keySet) { List sortedList = new ArrayList (); sortedList.addAll(keySet); Collections.sort(sortedList); return Collections.enumeration(sortedList); }
并覆盖在xml文件中保存已排序属性的stringPropertyNames()方法:
@Override public Set stringPropertyNames() { Set tmpSet = new TreeSet (); for (Object key : keySet()) { tmpSet.add(key.toString()); } return tmpSet; }
我通过覆盖方法商店做到了,像这样:
@Override public void store(Writer writer, String comments) throws IOException { this.keySet().stream().map(k -> (String)k).sorted().forEach(k -> { try { writer.append(String.format("%s=%s\n", k, get(k))); } catch (IOException e) { e.printStackTrace(); } }); }
以前的答案不适合我。