文章目录
P1 Properties文件
1 使用Properties文件存储配置信息
XML文件能够表示和存储层次结构的数据,但是有时对于“扁平”的数据,如单纯由键值对构成的简单配置信息,就可以使用Properties文件来存储
max = 30
min = 10
default = 20
2 创建一个Properties文件
P2 解析Properties文件
现在得到了这个简单的Properties文件,接下来就需要做一个简单的测试类,取出其中的信息,由于Properties文件中都是键值对,那么很自然地想到用HashMap来存储
解析过程程序:
package com.mec.properties;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Demo {
public static void main(String[] args) throws IOException {
//初始化一个存储properties文件中键值对的HashMap
Map<String, String> kvPool = new HashMap<>();
//取得文件流,新建一个Properties类对象
InputStream is = Class.class.getResourceAsStream("/config.properties");
Properties property = new Properties();
//加载文件
property.load(is);
String maxStr = property.getProperty("max");
String minStr = property.getProperty("min");
String defaultStr = property.getProperty("default");
System.out.println(
"max: " + maxStr + "\n"
+ "min: " + minStr + "\n"
+ "default: " + defaultStr);
//将property即properties文件中的键值对存储到HashMap中
//这里因为要从property的键集中遍历
//keySet()方法和get()方法的返回值
//都是Object对象,所以中间要进行类型转换
for(Object key : property.keySet()) {
String val = (String)property.get(key);
kvPool.put((String) key, val);
}
for(Object value : property.values()) {
System.out.println(value);
}
}
}
P3 将PropertiesParser做成工具
1 将键值对从磁盘加载到内存
上述的程序还是老问题,功能单一,过于片面只能处理一个Properties文件,为了推广程序的泛用性,这里依然选择将其作为工具,创建一个Properties文件的解析器,这个解析器将会从磁盘中将配置文件的键值对转化成内存中的HashMap,从而提高程序的泛用性和效率
2 HashMap应该是private
对于Properties文件,即某些配置文件,可能会在一个类或者多个类中使用它,也可能在一个类中重复使用它,我们不能让程序更改配置文件中的键值对,只能访问,所以HashMap必须是private修饰的,禁止其它程序对配置文件的内容进行修改
3 单例模式只产生一个对象
如果HashMap是private的,那么每次调用都会用构造器生成一个对象,这些对象是不同的,而且这里只需要一个HashMap即可,所以需要使用单例模式只产生一个对象即可
(1) 饿汉模式
package com.mec.porpertiesParser;
import java.util.HashMap;
import java.util.Map;
public class porpertiesParser {
//保证keyValueSet只有一份
private static Map<String, String> keyValueSet;
//类加载过程后,类实例化过程前初始化keyValueSet
static {
keyValueSet = new HashMap<>();
}
}
但是上述的程序有一个缺陷,即 饿汉模式,上述程序虽然保证了每个类中只产生一个对象,但每次在类加载过程时,就立刻执行static修饰的代码,假设一个软件中有很多类都需要解析配置文件,则该软件启动时,要做大量的初始化过程,就占用了大量的时间,降低了软件效率
(2) 懒汉模式
当JVM进行类加载过程时,static修饰成员或方法将先被加载一次,且只加载一次,当多个类都需要同一个配置文件的HashMap时,只需要产生一份即可,当需要使用时,先检测HashMap是否已经存在,如果存在则不需要再创建,即 懒汉模式
package com.mec.porpertiesParser;
import java.util.HashMap;
import java.util.Map;
public class porpertiesParser {
private static Map<String, String> keyValueSet;
public porpertiesParser() {
if(null == porpertiesParser.keyValueSet) {
porpertiesParser.keyValueSet = new HashMap<>();
}
}
}
使用懒汉模式,可以保证多个类共用一个对象,但上述的处理过程,还是需要创建一个对象,为了保证配置文件的安全,这里还是使用懒汉模式,静态块的处理方式,且使用private构造器,所有方法使用static,由类来调用方法
4 PropertiesParser解析器
package com.mec.propertiesParser;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class PropertiesParser {
//只产生一个HashMap
private static Map<String, String> keyValueSet;
//类加载过程后,类实例化过程前产生初始化keyValueSet
static {
PropertiesParser.keyValueSet = new HashMap<>();
}
//不产生对象,杜绝了外部的更改
private PropertiesParser() {
}
//加载过程,先根据文件名产生property对象
//然后加载,取键值对放入HashMap中
public static void loadProperties(String filePath) throws IOException {
InputStream is = Class.class.getResourceAsStream(filePath);
Properties property = new Properties();
if(null == is) {
return;
}
property.load(is);
for(Object key : property.keySet()) {
String val = (String)property.get(key);
keyValueSet.put((String)key, val);
}
}
}
//可以提供给用户使用的方法
//public static String getValue(String key) {
// return keyValueSet.get(key);
//}
//
//public static List<String> getKeys() {
//
// List<String> keys = new ArrayList<String>();
//
// for(Object key : keyValueSet.keySet()) {
// keys.add((String)key);
// }
//
// return keys;
//}
使用过程:
在原先的Util工程内,工具包内,新建一个PropertiesParser,将整个包导出成jar包,在需要的地方build path即可