事情背景:
在做Android项目开发时,有一个小功能是通过配置,判断对应的功能是否存在。 譬如: String fulluicctype = SystemProperties.get("vendor.gsm.ril.fulluicctype",""); 获取动态fulluicctype 判断是否包含"USIM"字符串。fulluicctype 要么为空,要么包含多组“单词“,
如:
String fulluicctype = "SIM,USIM,RUIM";
System.out.println(Arrays.binarySearch(fulluicctype.split(","), "USIM"));
运行结果: 1
可以说明,需要查找的"USIM"字符串,在fulluicctype用","分割的第二位。
但是,在测试过程中,还是测出来了新的问题,最新配置fulluicctype的内容发生了改变,变成fulluicctype = "USIM,RUIM,CSIM"; 没有想到匹配发生了问题。
如代码:
String fulluicctype = "USIM,RUIM,CSIM";
System.out.println(Arrays.binarySearch(fulluicctype.split(","), "USIM"));
运行结果: -4
通过源码查看原因:
找到源码并进行查看:
libcore/ojluni/src/main/java/java/util/Arrays.java
2275 /**
2276 * Searches the specified array for the specified object using the binary
2277 * search algorithm. The array must be sorted into ascending order
2278 * according to the
2279 * {@linkplain Comparable natural ordering}
2280 * of its elements (as by the
2281 * {@link #sort(Object[])} method) prior to making this call.
2282 * If it is not sorted, the results are undefined.
2283 * (If the array contains elements that are not mutually comparable (for
2284 * example, strings and integers), it <i>cannot</i> be sorted according
2285 * to the natural ordering of its elements, hence results are undefined.)
2286 * If the array contains multiple
2287 * elements equal to the specified object, there is no guarantee which
2288 * one will be found.
2289 *
2290 * @param a the array to be searched
2291 * @param key the value to be searched for
2292 * @return index of the search key, if it is contained in the array;
2293 * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The
2294 * <i>insertion point</i> is defined as the point at which the
2295 * key would be inserted into the array: the index of the first
2296 * element greater than the key, or <tt>a.length</tt> if all
2297 * elements in the array are less than the specified key. Note
2298 * that this guarantees that the return value will be >= 0 if
2299 * and only if the key is found.
2300 * @throws ClassCastException if the search key is not comparable to the
2301 * elements of the array.
2302 */
2303 public static int binarySearch(Object[] a, Object key) {
2304 return binarySearch0(a, 0, a.length, key);
2305 }
简单翻译一下:
使用二分搜索算法在指定数组中搜索指定对象。在调用之前,数组必须按照其元素的{@linkplain Comparable natural order}的升序排序(如{@link #sort(Object[])}方法)。如果没有排序,则结果是未定义的。(如果数组中包含的元素不具有可比性(例如字符串和整数),则不能按照元素的自然顺序排序,因此结果未定义。)如果数组包含与指定对象相等的多个元素,则不能保证找到哪个元素。
也就是说在使用二分法进行搜索时,要么是自然的顺序,譬如: 1,2,3,4. 要么是通过sort()方法进行排序。 假如是无序的,则获得的结果是不可预测的。
解决方案
将数组先进行使用sort方法排序,再使用.
String fulluicctype = "USIM,RUIM,CSIM";
String[] types = fulluicctype.split(",");
Arrays.sort(types);
System.out.println("types = " + Arrays.toString(types));
System.out.println(Arrays.binarySearch(types, "USIM"));
运行结果:
types = [CSIM, RUIM, USIM]
2
运行界面2表示,重新排完顺序之后,第三个值。
小结:
使用Arrays.binarySearch 一定要记得,先使用Arrays.sort()方法排序。