今天在生产环境联调的时候,发现一个很奇怪的问题,明明测试数据正确,结果却是结果不通过,经过debug查询到原来是Arrays.binarySearch用法错误,记录一下,避免后续再次犯错
具体测试如下:
想通过判断J是否存在数组中,结果发现出现如下错误
public static void main(String[] args) { String[] test ={"X","J","7","5","4","11","W8","W7"}; System.out.println("没排序结果 = [" + Arrays.binarySearch(test,"J") + "]"); }
运行结果:
没有排序 = [-7]
进行排序后判断:
public static void main(String[] args) { String[] test ={"X","J","7","5","4","11","W8","W7"}; System.out.println("没排序结果 = [" + Arrays.binarySearch(test,"J") + "]"); Arrays.sort(test); System.out.println("排序后结果 = [" + Arrays.binarySearch(test,"J") + "]"); }
运行结果:
没排序结果 = [-7] 排序后结果 = [4]
在网上查询下具体原因及查询官方解释如下:
/** * Searches the specified array for the specified object using the binary * search algorithm. The array must be sorted into ascending order * according to the * {@linkplain Comparable natural ordering} * of its elements (as by the * {@link #sort(Object[])} method) prior to making this call. * If it is not sorted, the results are undefined. * (If the array contains elements that are not mutually comparable (for * example, strings and integers), it <i>cannot</i> be sorted according * to the natural ordering of its elements, hence results are undefined.) * If the array contains multiple * elements equal to the specified object, there is no guarantee which * one will be found. * * @param a the array to be searched * @param key the value to be searched for * @return index of the search key, if it is contained in the array; * otherwise, <tt>(-(<i>insertion point</i>) - 1)</tt>. The * <i>insertion point</i> is defined as the point at which the * key would be inserted into the array: the index of the first * element greater than the key, or <tt>a.length</tt> if all * elements in the array are less than the specified key. Note * that this guarantees that the return value will be >= 0 if * and only if the key is found. * @throws ClassCastException if the search key is not comparable to the * elements of the array. */ public static int binarySearch(Object[] a, Object key) { return binarySearch0(a, 0, a.length, key); }
使用二分搜索法来搜索指定数组,以获得指定对象。在进行此调用之前,必须根据元素的自然顺序对数组进行升序排序(通过 sort(Object[]) 方法)。如果没有对数组进行排序,则结果是不确定的。(如果数组包含不可相互比较的元素(例如,字符串和整数),则无法 根据其元素的自然顺序对数组进行排序,因此结果是不确定的。)如果数组包含多个等于指定对象的元素,则无法保证找到的是哪一个,故所以会出现此问题
如果要判断数组中是否存在,可以使用 ArrayUtils.contains这个方法来判断是否存在,
/** * 校验服务类型是否符合枚举值 * @param possibility 可能性 * @param field 字段 * @param info 校验不通过的错误消息 * */ public void validatePossibility(String[] possibility,String field,ErrorInfo info){ boolean flag = ArrayUtils.contains(possibility,field); if (!flag) { throw getException(info) ; } }