English 中文(简体)
如何在java分类财产?
原标题:How to sort Properties in java?

我有一个<代码>Properties的标语,有时我需要添加其他<代码>Properties/code>。

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);

在此之后,我要打上<密码>。 我不想拿到所有钥匙和价值,将其打上<条码>。 是否有更好的办法?

最佳回答

编号:java.util.Properties > , > > 。

你可以尝试把所有价值都放在像<编码>java.util”这样的东西。 树冠(,这将对贵方的钥匙进行自然排序。

问题回答

all you have to do is create class which extends Properties. source: 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<String> keyList = new Vector<String>();
     while(keysEnum.hasMoreElements()){
       keyList.add((String)keysEnum.nextElement());
     }
     Collections.sort(keyList);
     return keyList.elements();
  }

}

它为我工作。

<keys work well with Java 8 <>em>, but since Java 9, the new implementation of methods store/code> 不用打上<代码>keys,但enterSet/code>。

因此,在储存时,你必须超越<条码>。

Here an example with inline overriding:

Properties properties = new Properties() {

    private static final long serialVersionUID = 1L;

    @Override
    public Set<Object> keySet() {
        return Collections.unmodifiableSet(new TreeSet<Object>(super.keySet()));
    }

    @Override
    public Set<Map.Entry<Object, Object>> entrySet() {

        Set<Map.Entry<Object, Object>> set1 = super.entrySet();
        Set<Map.Entry<Object, Object>> set2 = new LinkedHashSet<Map.Entry<Object, Object>>(set1.size());

        Iterator<Map.Entry<Object, Object>> iterator = set1.stream().sorted(new Comparator<Map.Entry<Object, Object>>() {

            @Override
            public int compare(java.util.Map.Entry<Object, Object> o1, java.util.Map.Entry<Object, Object> o2) {
                return o1.getKey().toString().compareTo(o2.getKey().toString());
            }
        }).iterator();

        while (iterator.hasNext())
            set2.add(iterator.next());

        return set2;
    }

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

www.un.org/spanish/ecosoc 用于java >的解决方案;8

尽管问题没有明确提及<代码>(OutputStream out, String comments)Function,但我认为这(和load(InputStream inStream)分别属于<编码>Properties的最有趣部分。

如果我们不关心storing/loading nature<>/strong>,我们就只能取代Properties和一些MapSortedMap执行。

与<代码>Map相比,/code>上的区别在于store(>/load( 提供一定专用序列化规则>的方法。 这些规则没有(也不会)改变各支离破碎版本。 e.g.

  • Storing pairs like prop=value
  • Escaping rules for unicode and special characters.
  • Adding optional comment on top

Unfortunately the above 3 parts of the functionality are hidden inside private methods, and cannot be easily re-used inside extended or alternative implementations that wish to use different internal data-structures (e.g. for keeping properties sorted).

因此,剩下的是 维护同样的内部结构,超越了两个<代码>的储存( 方法

Note: For getting sorted properties, some time ago I followed danisupr4 implementation, but on java9 it broke.

TL;DR

The code below maintains the full functionality of Properties by overriding only store(OutputStream out, String comments) method, and is tested with all versions from java5 - java12.
I believe that filtering the output of this public method makes the implementation less fragile to future code changes in java.util.Properties class.


    class SortedStoreProperties extends Properties {
    
        @Override
        public void store(OutputStream out, String comments) throws IOException {
            Properties sortedProps = new Properties() {
                @Override
                public Set<Map.Entry<Object, Object>> entrySet() {
                    /*
                     * Using comparator to avoid the following exception on jdk >=9: 
                     * java.lang.ClassCastException: java.base/java.util.concurrent.ConcurrentHashMap$MapEntry cannot be cast to java.base/java.lang.Comparable
                     */
                    Set<Map.Entry<Object, Object>> sortedSet = new TreeSet<Map.Entry<Object, Object>>(new Comparator<Map.Entry<Object, Object>>() {
                        @Override
                        public int compare(Map.Entry<Object, Object> o1, Map.Entry<Object, Object> o2) {
                            return o1.getKey().toString().compareTo(o2.getKey().toString());
                        }
                    }
                    );
                    sortedSet.addAll(super.entrySet());
                    return sortedSet;
                }
    
                @Override
                public Set<Object> keySet() {
                    return new TreeSet<Object>(super.keySet());
                }
    
                @Override
                public synchronized Enumeration<Object> keys() {
                    return Collections.enumeration(new TreeSet<Object>(super.keySet()));
                }
    
            };
            sortedProps.putAll(this);
            sortedProps.store(out, comments);
        }
    }

注:视何人称<代码>store()而定,最好不要凌驾于现有方法之上,而是建立新的方法:例如storeSorted(<>

NOTE:

For simplicity I override only one of the two store() methods but the same concept applies to both.

<>strong>@danisupr4有最佳解决办法。

我会稍加改进,这样,你才能在我们的民主与发展协会获得任何警告:

public static class MyProperties extends Properties {
    private static final long serialVersionUID = 1L;

    public Enumeration<Object> keys() {
        Enumeration<Object> keysEnum = super.keys();
        Vector<Object> keyList = new Vector<Object>();

        while (keysEnum.hasMoreElements()) {
            keyList.add(keysEnum.nextElement());
        }

        Collections.sort(keyList, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                return o1.toString().compareTo(o2.toString());
            }
        });

        return keyList.elements();
    }
}

树苗应当是最简单的方式:

Properties myProps = this.getClass.getResourceAsStream(MY_PROPS_PATH);

try {
    myProps.load(new FileInputStream(extraPropertiesFilename));
        //you can load more properties from external file

    Map<String, String> 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();
}

更简单地确定关键:

List<String> keys = new ArrayList<String>()
for(String key : properties.stringPropertyNames()) {
  keys.add(key)
}

Collections.sort(keys);

在 Java8,Properties.keys()被用于储存这些财产,在 Java9,这一改动和。 使用:

Java 8

private void store0(BufferedWriter bw, String comments, boolean escUnicode)
    throws IOException
{
...
        for (Enumeration<?> e = keys(); e.hasMoreElements();) {

Java 9

private void store0(BufferedWriter bw, String comments, boolean escUnicode)
    throws IOException
{
...
        for (Map.Entry<Object, Object> e : entrySet()) {

我利用这一班子处理 both两种版本:

public class SortedProperties extends Properties {

    /**
     * constructor
     *
     * @param unsortedProperties
     */
    public SortedProperties(Properties unsortedProperties) {
        putAll(unsortedProperties);
    }

    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public synchronized Enumeration keys() {
        Enumeration<Object> keysEnum = super.keys();
        Vector<String> keyList = new Vector<String>();
        while (keysEnum.hasMoreElements()) {
            keyList.add((String) keysEnum.nextElement());
        }
        Collections.sort(keyList);
        return keyList.elements();
    }

    @Override
    public Set<java.util.Map.Entry<Object, Object>> entrySet() {
        // use a TreeMap since in java 9 entrySet() instead of keys() is used in store()
        TreeMap<Object, Object> treeMap = new TreeMap<>();
        Set<Map.Entry<Object, Object>> entrySet = super.entrySet();
        for (Map.Entry<Object, Object> entry : entrySet) {
            treeMap.put(entry.getKey(), entry.getValue());
        }
        return Collections.synchronizedSet(treeMap.entrySet());
    }
}

您可以推翻在txt档案中保存分类财产的关键方法:

//this method downloaded from edu.umd.cs.findbugs.config package
@SuppressWarnings("unchecked")
@Override
public synchronized Enumeration<Object> keys() {
    Set<?> set = keySet();
    return (Enumeration<Object>) sortKeys((Set<String>) set);
}
static public Enumeration<?> sortKeys(Set<String> keySet) {
    List<String> sortedList = new ArrayList<String>();
    sortedList.addAll(keySet);
    Collections.sort(sortedList);
    return Collections.enumeration(sortedList);
}

和压倒性斯特恩(V)法,在Xml档案中保存分类财产:

@Override
public Set<String> stringPropertyNames() {
Set<String> tmpSet = new TreeSet<String>();
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
", k, get(k)));
        } catch (IOException e) {
            e.printStackTrace();
        }
    });

}

Previous answers hadn t fit well for me.

Try using a TreeMap (that sorts the key in natural order) and StringBuilder (we can use sysout also, but it is easy to log(slf4j) the return value)

public static String getPrettyPrintProps(Properties properties) {
Map<String, String> map = new TreeMap(properties);
StringBuilder sb = new StringBuilder();
map.forEach((k, v) -> sb.append("
" + k + ":" + v ) );
return  sb.toString();
}

如何:

    System.getProperties().entrySet().stream()
            .sorted((e1, e2) -> e1.getKey().toString().compareToIgnoreCase(e2.getKey().toString()))

我的简单解决办法是,每次阅读、分类和写字。 视你使用的情况而定,这可能是最简单的解决办法,不需要扩大“收益”。

As I purely do the sorting of the lines all semantics like escaping etc is untouched. As "#" will automatically be on the top with default String sorting.

当然,你也可以利用你喜欢的档案图书馆这样做。 我使用java.nio.file。 这里的文件就是一例。

  List<String> lines = Files.readAllLines(propertiesFile, CHARSET).stream().sorted().toList();

  Files.write(propertiesFileFile, lines, CHARSET, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...