论坛首页 Java企业应用论坛

【飞天奔月出品】Properties 转换成Map【实用小技巧】

浏览 5151 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-01-03  
今天做项目过程中,遇到了个  Properties 转换成Map 的地方

第一时间想到的肯定有以下:
1.  迭代出来  再 put 到 map 中去

2. commons 是否有工具类 




可是 由于 Properties  实现了Map 接口,  所以有最最简单的 ,强制转换




package com.feilong.example.util;

import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;

public class PropertiesToMap {
    public static void main(String[] args) {

        Properties properties = new Properties();


        properties.setProperty("StrictHostKeyChecking", "no");
        properties.setProperty("app.version", "1.0");

        // Create a new HashMap and pass an instance of Properties. Properties
        // is an implementation of a Map which keys and values stored as in a string.
        Map<String, String> map = new HashMap<String, String>((Map) properties);


        // Get the entry set of the Map and print it out.

        Set propertySet = map.entrySet();
        for (Object o : propertySet) {
            Map.Entry entry = (Map.Entry) o;
            System.out.printf("%s = %s%n", entry.getKey(), entry.getValue());
        }
    }
}
 
   发表时间:2013-01-04  
发表下观点

这就叫不重复发明轮子.并且
Map<String, String> map = new HashMap<String, String>((Map) properties);由这个构造函数构造的HashMap底层一样是迭代器Iterator完成init的.

0 请登录后投票
   发表时间:2013-01-04  
既然properties 实现了 Map接口 ,  为啥你还去强转呢
0 请登录后投票
   发表时间:2013-01-05  
Properties 使用要小心
http://jinnianshilongnian.iteye.com/blog/1703777
引用

原因很简单:API不熟造成的:
1、首先我们来看下Properties构造器定义:
javadoc 写道
public Properties(Properties defaults)创建一个带有指定默认值的空属性列表。

参数:
defaults - 默认值。

    1)、构造器第一个参数是默认值;
    2)、当我们使用getProperty(key) 时,首先查自己的prop,如果有直接返回,否则查defaults中的key。
javadoc 写道
public String getProperty(String key)
用指定的键在此属性列表中搜索属性。如果在此属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回 null。
3)、原因到此很明显了,此时我们使用#{props.getProperty('a')} 其实是查的defaults
4)、Properties本身继承了Hashtable,其实是一种错误的用法,造成了我们现在的我们现在的问题,get(key)只查自己,而getProperty会先查自己 再查defaults。
0 请登录后投票
   发表时间:2013-01-05  
shenliuyang 写道
既然properties 实现了 Map接口 ,  为啥你还去强转呢



这个问题 问得好






直接表现 就是 如果不强转 , ide 会报错,   map 没有 The constructor (Properties)  这样的构造



properties  和  Map  确实和 jinnianshilongnian  所说的  关系微妙




  • 大小: 26.2 KB
0 请登录后投票
   发表时间:2013-01-05  
cectsky 写道
发表下观点

这就叫不重复发明轮子.并且
Map<String, String> map = new HashMap<String, String>((Map) properties);由这个构造函数构造的HashMap底层一样是迭代器Iterator完成init的.




跟进源码,确实是这样的




    /**
     * Constructs a new <tt>HashMap</tt> with the same mappings as the
     * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
     * default load factor (0.75) and an initial capacity sufficient to
     * hold the mappings in the specified <tt>Map</tt>.
     *
     * @param   m the map whose mappings are to be placed in this map
     * @throws  NullPointerException if the specified map is null
     */
    public HashMap(Map<? extends K, ? extends V> m) {
        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
                      DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
        putAllForCreate(m);
    }



会调用  private putAllForCreate


    private void putAllForCreate(Map<? extends K, ? extends V> m) {
        for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<? extends K, ? extends V> e = i.next();
            putForCreate(e.getKey(), e.getValue());
        }
    }




会调用  private putForCreate

    /**
     * This method is used instead of put by constructors and
     * pseudoconstructors (clone, readObject).  It does not resize the table,
     * check for comodification, etc.  It calls createEntry rather than
     * addEntry.
     */
    private void putForCreate(K key, V value) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);

        /**
         * Look for preexisting entry for key.  This will never happen for
         * clone or deserialize.  It will only happen for construction if the
         * input Map is a sorted map whose ordering is inconsistent w/ equals.
         */
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k)))) {
                e.value = value;
                return;
            }
        }

        createEntry(hash, key, value, i);
    }

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics