String.CompareToコンパレータを使用して、文字列の静的配列を並べ替えてバイナリ検索したいと思います。
問題は、ソートとバイナリ検索の両方でComparatorオブジェクトを渡す必要があることです-では、組み込みの文字列コンパレータを渡すにはどうすればよいですか?
String.CompareToコンパレータを使用して、文字列の静的配列を並べ替えてバイナリ検索したいと思います。
問題は、ソートとバイナリ検索の両方でComparatorオブジェクトを渡す必要があることです-では、組み込みの文字列コンパレータを渡すにはどうすればよいですか?
独自のコンパレータを作成できます
public class ExampleComparator implements Comparator<String> {
public int compare(String obj1, String obj2) {
if (obj1 == obj2) {
return 0;
}
if (obj1 == null) {
return -1;
}
if (obj2 == null) {
return 1;
}
return obj1.compareTo(obj2);
}
}
java.util.Comparator.comparing(...)に基づくJava 8のソリューション:
Comparator<String> c = Comparator.comparing(String::toString);
また
Comparator<String> c = Comparator.comparing((String x) -> x);
このArrays
クラスには、のバージョンがあり、を必要sort()
とbinarySearch()
しませんComparator.
。たとえば、オブジェクトの配列のみを受け取るバージョンをArrays.sort()
使用できます。これらのメソッドcompareTo()
は、配列内のオブジェクトのメソッドを呼び出します。
yourslefがを必要としていることに気づきComparator
、すでにを使用している場合はGuava
、を使用できますOrdering.natural()
。
これは数年後ですが、Java 8ではComparator.naturalOrder()を使用できます。
http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder--
javadocから:
static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
Comparableオブジェクトを自然な順序で比較するコンパレータを返します。返されたコンパレータはシリアライズ可能であり、nullを比較するときにNullPointerExceptionをスローします。
Comparator
これは、次のようなオブジェクトだけでなく、あらゆる種類のComparable
オブジェクトのジェネリックString
です。
package util;
import java.util.Comparator;
/**
* The Default Comparator for classes implementing Comparable.
*
* @param <E> the type of the comparable objects.
*
* @author Michael Belivanakis (michael.gr)
*/
public final class DefaultComparator<E extends Comparable<E>> implements Comparator<E>
{
@SuppressWarnings( "rawtypes" )
private static final DefaultComparator<?> INSTANCE = new DefaultComparator();
/**
* Get an instance of DefaultComparator for any type of Comparable.
*
* @param <T> the type of Comparable of interest.
*
* @return an instance of DefaultComparator for comparing instances of the requested type.
*/
public static <T extends Comparable<T>> Comparator<T> getInstance()
{
@SuppressWarnings("unchecked")
Comparator<T> result = (Comparator<T>)INSTANCE;
return result;
}
private DefaultComparator()
{
}
@Override
public int compare( E o1, E o2 )
{
if( o1 == o2 )
return 0;
if( o1 == null )
return 1;
if( o2 == null )
return -1;
return o1.compareTo( o2 );
}
}
使用方法String
:
Comparator<String> stringComparator = DefaultComparator.getInstance();
Arrays.binarySearch(Object[] a, Object key)
繰り返しになりますが、オブジェクトのタイプが比較可能である限り、コンパレータは必要ありませんが、ラムダ式を使用すると、これがはるかに簡単になります。
コンパレータをメソッドリファレンスに置き換えるだけです。String::compareTo
例えば:
Arrays.binarySearch(someStringArray, "The String to find.", String::compareTo);
あなたも使うことができます
Arrays.binarySearch(someStringArray, "The String to find.", (a,b) -> a.compareTo(b));
しかし、ラムダの前でさえ、常に匿名クラスがありました:
Arrays.binarySearch(
someStringArray,
"The String to find.",
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
また、大文字と小文字を区別しない比較が必要な場合、最近のバージョンのJavaでは、最近見つけたように、String
クラスにはタイプがpublic static final
呼ばれるフィールドが含まれています。したがって、を使用して作業を完了することができます。CASE_INSENSITIVE_ORDER
Comparator<String>
String.CASE_INSENSITIVE_ORDER
String.CASE_INSENSITIVE_ORDERコンパレータを使用して、大文字と小文字を区別しない順序で文字列を比較できます。
Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);
Mike Nakisの良い答えをで一般化するにはString.CASE_INSENSITIVE_ORDER
、次を使用することもできます。
Collator.getInstance();
Collatorを参照してください
ナンバリの答えに関しては間違いがありました。二重等号==を使用して値を比較する場合、誰かが新しいキーワードを使用してStringオブジェクトを作成しない限り、プログラムはcompareメソッドに到達しません。これはベストプラクティスではありません。これは少し良い解決策かもしれません:
public int compare(String o1, String o2) {
if (o1 == null && o2 == null){return 0;}
if (o1 == null) { return -1;}
if (o2 == null) { return 1;}
return o1.compareTo(o2);
}
PSコメントありがとうございます;)
あなたは使用することができますStringUtils.compare("a", "b")