我正在尝试在运行时读取Java系统属性,基于includes
列表(此处硬编码但通常通过属性文件注入)进行过滤,最后按键排序,转换为Map<String, String>
。这就是我提出的,但不确定它是否是最优雅的解决方案。
final List<String> includes = Arrays
.asList("java.version", "PID", "os.name", "user.country"); // hard coded here but (usually defined in a properties file)
Map<String, String> systemMap = System.getProperties()
.entrySet().stream()
.filter(s -> includes != null && includes.contains(s.getKey()))
.sorted(Comparator.comparing(
Map.Entry::getKey, Comparator.comparing(e -> (String) e))
)
.collect(Collectors.toMap(
e -> (String) e.getKey(),
e -> (String) e.getValue(),
(e1, e2) -> e2,
LinkedHashMap::new)
);
我很想知道代码是否可以整理。
答案 0 :(得分:5)
如何反转它并使用stream
列表的includes
代替?这样,您不必一直解压缩这些地图条目,您只需使用sorted
,如果includes
仅包含有效的属性,您可能甚至不需要{{1 }}。 (另外,在地图中查找比列表中的查找更快,但这可能并不重要。)
filter
答案 1 :(得分:2)
这里的“好”部分是Properties extends Hashtable<Object,Object>
,它是问题的根源。不出所料,System.getProperties().entrySet()
会返回Set<Map.Entry<Object, Object>>
。
因此,在进行过滤和排序之前,我们需要一个额外的映射操作将每个Entry<Object, Object>
转换为Entry<String, String>
:
final Map<String, String> map = System.getProperties()
.entrySet()
.stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey().toString(), e.getValue().toString()))
.filter(e -> includes.contains(e.getKey()))
.sorted(Comparator.comparing(AbstractMap.SimpleEntry::getKey))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
方法引用看起来很模糊,因此最后2个操作将使用较短的lambda表达式:
.sorted(Comparator.comparing(e -> e.getKey()))
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
另一种选择是迭代includes
列表,该列表似乎小于System.getProperties()
:
final Properties properties = System.getProperties();
final Map<String, String> map2 = includes
.stream()
.filter(properties::containsKey)
.sorted()
.collect(Collectors.toMap(Function.identity(), properties::getProperty));
答案 2 :(得分:2)
我的意见是,过滤器4的所有属性(大约100)都不是最理想的。
我的建议是:
// hard coded here but (usually defined in a properties file)
final List<String> includes = Arrays.asList("java.version", "PID",
"os.name", "user.country");
Map<String, String> systemMap = includes.stream()
.collect(Collectors.toMap(e -> e,
e -> System.getProperty(e)));
更新:排序版
final List<String> includes = Arrays.asList("java.version", "PID",
"os.name", "user.country");
Map<String, String> systemMap = includes.stream()
.collect(Collectors.toMap(e -> e,
e -> System.getProperty(e),
(e1, e2) -> e2,
TreeMap::new));
return systemMap;