项目场景:
? ? ? ? 在用SharedPreferences存储数据时,由于要存储多个值,API中有个putStringSet(String?key,?Set<String> values) 方法好像满足这个要求,然后用此方法实现需求,在getStringSet(String key)时发现取值和存值顺序不一致的现象
问题描述:
???????? 项目中,String? key = "com.android.baidu"
? ? ? ? ?然后通过包名来存储如下值:
? ? ? ? ? 应用的名称: String AppName;
? ? ? ? ? 应用的版本号: String? currentVersion;
? ? ? ? ? 应用的安装来源:String? origin;
? ? ? ? ??
存值:
SharedPreferences.Editor editor = preferenses.edit();
Set<String> appInfoSet = new HashSet<>();
appInfoSet.add(appVersion);
appInfoSet.add(appName);
appInfoSet.add(origin);
editor.putStringSet(pkgName, appInfoSet) // 存值顺序: 版本号 应用名 安装来源
取值:
appInfoSet = editor.getStringSet(pkgName);
if (appInfoSet.size() > 0) {
//转换成数组
String[] data = appInfoSet.toArray(new String[appInfoSet.size()]);
appVersion = data[0];
appName = data[1];
origin = data[2];
}
//本以为可以正常对应获取到存的值, 但是发现每执行一次:
实际获取的情况 key:value 对不上
appVersion : 百度.apk
appName : 1.0.1
origin : 浏览器
appVersion : 浏览器
appName : 百度.apk
origin : 1.0.1
//好奇怪???
原因分析:
????????看下了源码,发现存储过程用的是 HashSet ,它实现了set接口,不允许集合中有重复的值,仅仅是存储对象,它是一个无序的集合,所以你每次getStringSet的获取值顺序不一样。
??
? ? ??
解决方案:
? ? ? ? 【第一个方案】:存端:? ?用数字0 , 1, 2? 开头,拼接字符串;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??取端: 使用Arrays. sort() 方法升序排序,去掉开头一位,获取目标字符串
? ?? ??
存值:
SharedPreferences.Editor editor = preferenses.edit();
Set<String> appInfoSet = new HashSet<>();
//数字前缀,相当于做一个顺序标记
appInfoSet.add("0"+appVersion);
appInfoSet.add("1"+appName);
appInfoSet.add("2"+origin);
editor.putStringSet(pkgName, appInfoSet) // 存值顺序: 版本号 应用名 安装来源
取值:
appInfoSet = editor.getStringSet(pkgName);
if (appInfoSet.size() > 0) {
//转换成数组
String[] data = appInfoSet.toArray(new String[appInfoSet.size()]);
//对指定对象进行 升序排列
Arrays.sort(data);
//截取字符串
appVersion = data[0].substring(1);
appName = data[1].substring(1);
origin = data[2].substring(1);
}
????????【第二个方案】:存端:??把上面3个值,拼接成一个字符串, 用“:" 来隔开 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?取端:? 用String.split(":") 去还原字符串
//存值:
String dataString = appVersion + ":" + appName + ":" + appOriginString;
editor.saveString(pkgName, dataString);
//取值:
String dataString = editor.getString(pkgName);
if (!dataString.isEmpty()) {
//返回由指定数组支持的固定大小的列表。
List<String> data = new ArrayList<>(Arrays.asList(dataString.split(":")));
appVersion = data.get(0);
appName = data.get(1);
appOriginString = data.get(2);
}
|