Java Tutorial/Collections/Collections Search
Содержание
- 1 A binary search implementation.
- 2 Binary Searching
- 3 Binary search routines
- 4 Check whether the given Collection contains the given element instance.
- 5 Find a value of the given type in the given Collection
- 6 Get the difference of two collections
- 7 Return the first element in "candidates" that is contained in source
A binary search implementation.
<source lang="java">
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don"t indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */
// ---------------------------------------------------------------------------- /**
* A binary search implementation. */
public class BinarySearch {
public int find(final int[] data, final int key) { int low = 0, high = data.length - 1; while (low <= high) { final int i = (low + high) >> 1; final int v = data[i]; if (v == key) return i; // this line does not get covered unless there is a match else if (v < key) low = i + 1; else // v > key high = i - 1; } return -1; }
}</source>
Binary Searching
<source lang="java">
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class MainClass {
public static void main(String args[]) { String str[] = { "B", "H", "L", "M", "I", "N", "R" }; // Convert to list List list = new ArrayList(Arrays.asList(str)); // Ensure list sorted Collections.sort(list); System.out.println("Sorted list: [length: " + list.size() + "]"); System.out.println(list); // Search for element in list int index = Collections.binarySearch(list, "M"); System.out.println("Found M @ " + index); // Search for element not in list index = Collections.binarySearch(list, "J"); System.out.println("Didn"t find J @ " + index); // Insert int newIndex = -index - 1; list.add(newIndex, "J"); System.out.println("With J added: [length: " + list.size() + "]"); System.out.println(list); }
}</source>
Sorted list: [length: 7] [B, H, I, L, M, N, R] Found M @ 4 Didn"t find J @ -4 With J added: [length: 8] [B, H, I, J, L, M, N, R]
Binary search routines
<source lang="java">
/*
* Copyright (c) 1998-2002 Carnegie Mellon University. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS"" AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
/**
* Binary search routines. */
public abstract class BinarySearch {
/** * Search a sorted array of integers. * @param array Array of integers * @param offset Starting offset of subarray to search * @param length Length of subarray to search * @param x Value to search for * @return largest index i in subarray (offset <= i <= offset+length) * such that all elements below i in the subarray are strictly less * than x. If x is found in the subarray, then array[i] == x (and i is * the first occurence of x in the subarray). If x is not found, * then array[i] is where x should be inserted in the sort order. */ public static int search (int[] array, int offset, int length, int x) { // handle 0-length subarray case right away if (length <= 0) return offset; int low = offset; int high = offset+length-1; // since length > 0, array[low] and array[high] are valid indices if (x <= array[low]) return low; if (x > array[high]) return high+1; while (low+1 < high) { // loop invariant: array[low] < x <= array[high], // offset <= low < high < offset+length int mid = (low + high)/2; if (x <= array[mid]) high = mid; else low = mid; } // now we have array[low] < x <= array[high] // && (low+1 == high || low == high) // implies low+1 == high //debug.assertion (low+1 == high); return high; }
}</source>
Check whether the given Collection contains the given element instance.
<source lang="java">
import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; /*
* Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* Miscellaneous collection utility methods. * Mainly for internal use within the framework. * * @author Juergen Hoeller * @author Rob Harrop * @since 1.1.3 */
abstract class CollectionUtils {
/** * Check whether the given Collection contains the given element instance. * Enforces the given instance to be present, rather than returning *true
for an equal element as well. * @param collection the Collection to check * @param element the element to look for * @returntrue
if found,false
else */ public static boolean containsInstance(Collection collection, Object element) { if (collection != null) { for (Iterator it = collection.iterator(); it.hasNext();) { Object candidate = it.next(); if (candidate == element) { return true; } } } return false; } /** * Returntrue
if the supplied Collection isnull
* or empty. Otherwise, returnfalse
. * @param collection the Collection to check * @return whether the given Collection is empty */ public static boolean isEmpty(Collection collection) { return (collection == null || collection.isEmpty()); } /** * Returntrue
if the supplied Map isnull
* or empty. Otherwise, returnfalse
. * @param map the Map to check * @return whether the given Map is empty */ public static boolean isEmpty(Map map) { return (map == null || map.isEmpty()); }
/** * Returntrue
if any element in "candidates
" is * contained in "source
"; otherwise returnsfalse
. * @param source the source Collection * @param candidates the candidates to search for * @return whether any of the candidates has been found */ public static boolean containsAny(Collection source, Collection candidates) { if (isEmpty(source) || isEmpty(candidates)) { return false; } for (Iterator it = candidates.iterator(); it.hasNext();) { if (source.contains(it.next())) { return true; } } return false; } /** * Return the first element in "candidates
" that is contained in * "source
". If no element in "candidates
" is present in * "source
" returnsnull
. Iteration order is * {@link Collection} implementation specific. * @param source the source Collection * @param candidates the candidates to search for * @return the first present object, ornull
if not found */ public static Object findFirstMatch(Collection source, Collection candidates) { if (isEmpty(source) || isEmpty(candidates)) { return null; } for (Iterator it = candidates.iterator(); it.hasNext();) { Object candidate = it.next(); if (source.contains(candidate)) { return candidate; } } return null; } /** * Find a value of the given type in the given Collection. * @param collection the Collection to search * @param type the type to look for * @return a value of the given type found, ornull
if none * @throws IllegalArgumentException if more than one value of the given type found */ public static Object findValueOfType(Collection collection, Class type) throws IllegalArgumentException { if (isEmpty(collection)) { return null; } Class typeToUse = (type != null ? type : Object.class); Object value = null; for (Iterator it = collection.iterator(); it.hasNext();) { Object obj = it.next(); if (typeToUse.isInstance(obj)) { if (value != null) { throw new IllegalArgumentException("More than one value of type [" + typeToUse.getName() + "] found"); } value = obj; } } return value; } /** * Determine whether the given Collection only contains a single unique object. * @param collection the Collection to check * @returntrue
if the collection contains a single reference or * multiple references to the same instance,false
else */ public static boolean hasUniqueObject(Collection collection) { if (isEmpty(collection)) { return false; } boolean hasCandidate = false; Object candidate = null; for (Iterator it = collection.iterator(); it.hasNext();) { Object elem = it.next(); if (!hasCandidate) { hasCandidate = true; candidate = elem; } else if (candidate != elem) { return false; } } return true; }
}</source>
Find a value of the given type in the given Collection
<source lang="java">
import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; /*
* Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* Miscellaneous collection utility methods. * Mainly for internal use within the framework. * * @author Juergen Hoeller * @author Rob Harrop * @since 1.1.3 */
abstract class CollectionUtils {
/** * Find a value of the given type in the given Collection. * @param collection the Collection to search * @param type the type to look for * @return a value of the given type found, ornull
if none * @throws IllegalArgumentException if more than one value of the given type found */ public static Object findValueOfType(Collection collection, Class type) throws IllegalArgumentException { if (isEmpty(collection)) { return null; } Class typeToUse = (type != null ? type : Object.class); Object value = null; for (Iterator it = collection.iterator(); it.hasNext();) { Object obj = it.next(); if (typeToUse.isInstance(obj)) { if (value != null) { throw new IllegalArgumentException("More than one value of type [" + typeToUse.getName() + "] found"); } value = obj; } } return value; } /** * Returntrue
if the supplied Collection isnull
* or empty. Otherwise, returnfalse
. * @param collection the Collection to check * @return whether the given Collection is empty */ public static boolean isEmpty(Collection collection) { return (collection == null || collection.isEmpty()); } /** * Returntrue
if the supplied Map isnull
* or empty. Otherwise, returnfalse
. * @param map the Map to check * @return whether the given Map is empty */ public static boolean isEmpty(Map map) { return (map == null || map.isEmpty()); }
/** * Return the first element in "candidates
" that is contained in * "source
". If no element in "candidates
" is present in * "source
" returnsnull
. Iteration order is * {@link Collection} implementation specific. * @param source the source Collection * @param candidates the candidates to search for * @return the first present object, ornull
if not found */ public static Object findFirstMatch(Collection source, Collection candidates) { if (isEmpty(source) || isEmpty(candidates)) { return null; } for (Iterator it = candidates.iterator(); it.hasNext();) { Object candidate = it.next(); if (source.contains(candidate)) { return candidate; } } return null; }
/** * Determine whether the given Collection only contains a single unique object. * @param collection the Collection to check * @returntrue
if the collection contains a single reference or * multiple references to the same instance,false
else */ public static boolean hasUniqueObject(Collection collection) { if (isEmpty(collection)) { return false; } boolean hasCandidate = false; Object candidate = null; for (Iterator it = collection.iterator(); it.hasNext();) { Object elem = it.next(); if (!hasCandidate) { hasCandidate = true; candidate = elem; } else if (candidate != elem) { return false; } } return true; }
}</source>
Get the difference of two collections
<source lang="java">
import java.util.ArrayList; import java.util.Collection;
public class Utils {
public static <T> Collection<T> diff(Collection<T> c1, Collection<T> c2) { if (c1 == null || c1.size() == 0 || c2 == null || c2.size() == 0) { return c1; } Collection<T> difference = new ArrayList<T>(); for (T item : c1) { if (!c2.contains(item)) { difference.add(item); } } return difference;
}
}</source>
Return the first element in "candidates" that is contained in source
<source lang="java">
import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; /*
* Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* Miscellaneous collection utility methods. * Mainly for internal use within the framework. * * @author Juergen Hoeller * @author Rob Harrop * @since 1.1.3 */
abstract class CollectionUtils {
/** * Return the first element in "candidates
" that is contained in * "source
". If no element in "candidates
" is present in * "source
" returnsnull
. Iteration order is * {@link Collection} implementation specific. * @param source the source Collection * @param candidates the candidates to search for * @return the first present object, ornull
if not found */ public static Object findFirstMatch(Collection source, Collection candidates) { if (isEmpty(source) || isEmpty(candidates)) { return null; } for (Iterator it = candidates.iterator(); it.hasNext();) { Object candidate = it.next(); if (source.contains(candidate)) { return candidate; } } return null; } /** * Returntrue
if the supplied Collection isnull
* or empty. Otherwise, returnfalse
. * @param collection the Collection to check * @return whether the given Collection is empty */ public static boolean isEmpty(Collection collection) { return (collection == null || collection.isEmpty()); } /** * Returntrue
if the supplied Map isnull
* or empty. Otherwise, returnfalse
. * @param map the Map to check * @return whether the given Map is empty */ public static boolean isEmpty(Map map) { return (map == null || map.isEmpty()); }
}</source>