4

私はこのようなものをコーディングしています:

List<Bean> beans = service.findBeans();
Collections.sort(beans, new BeanComparator());
return beans;

それは完全に機能します。私が探しているのは、たった1行でこれを行うためのショートカットです:

return somelibrary.Collections.sort(service.findBeans(), new BeanComparator());

または:

return somelibrary.newList(service.findBeans(), new BeanComparator());

変更可能なリストが必要であることに注意してください。

4

6 に答える 6

12

これは1行です:

List<Bean> beans = service.findBeans(); Collections.sort(beans, new BeanComparator()); return beans;

しかし、もっと深刻なことに、Java はワンライナーに適した言語ではありません。また、ワンライナーだからといって、それが優れているとは限りません。たとえば、私は最初、次のことを発見して驚きました。

return condition ? a : b;

よりも長いバイトコードを作成します

if( condition )
    return a;
else
    return b;

しかし、それが言語とコンパイラのあり方です。

ワンライナーを主張する場合、Guavaはそれを行うことがOrderingできます:

return Ordering.from( new BeanComparator() ).sortedCopy( service.findBeans() );

返されるリストは、変更可能でシリアライズ可能で、ランダム アクセスが可能です。

効率的には、オーバーヘッドの点で少し無駄があると思います。また、サードパーティのライブラリに依存するようになりました。基本的に、非常に単純なタスクに対して非常に強力なツールを使用することになります。これだけ使うとやり過ぎです。

于 2012-05-22T19:39:11.427 に答える
4

次の関数があなたが望む結果をもたらすと信じています。好きなクラスに入れるだけ。

public static <T> List<T> sort(List<T> list, Comparator<? super T> compare) {
    Collections.sort(list, compare);
    return list;
}
于 2012-05-22T19:32:22.817 に答える
2

apache CollectionUtils を使用して、リストをコンパレータと空のリストで照合できます。

CollectionUtils.collate(service.findBeans().iterator(),Collections.EMPTY_LIST.iterator(),new beanComparator())

CollectionUtils は、並べ替えられたリストを返すユーティリティ メソッドを追加する必要があります...

use-more-lines に対する古典的な反論は LOGGING です。読みやすくするためにログを記録する場合は、1 行しか使用しないでください。コードが実際に何を行っているかを調べようとするとき、ロギングは静的ノイズですが、ロギングはかなり重要です。

そのため、ロギングはコンパクト (1 行) で静か (例外をスローしない/nullsafe である必要があります) である必要があり、パフォーマンスが高い必要があります (オフにした場合、isDebugOn() チェックを超えて余分な処理が導入されないようにする必要があります)。

2 番目の反論は、JOOQ などの流暢なインターフェースであり、はるかに普及しつつあります。

于 2014-12-29T19:51:22.613 に答える
1

投稿された元の質問は有効だと思います。「Collections.sort(..)」メソッドには、渡されたコレクションを並べ替えるという意図的な副作用があるため、元のコレクションを維持したい場合は、次のことを行う必要があります。

List<Bean> beans = service.findBeans();
List<Bean> sortedBeans = new ArrayList<Bean>(beans);
Collections.sort(sortedBeans, new BeanComparator());
return sortedBeans;

上記の場合、サービス メソッドによって返された Collection を並べ替えるのは、おそらくそれほど大きな問題ではありません。しかし、並べ替えているコレクションがメソッド パラメーターであり、呼び出し元が渡されたコレクションを並べ替えたくない場合はどうなるでしょうか。

私は通常、結果のないメソッドを好む。

「Collections.sort(..)」はリストに影響するため、次のコードを記述する必要があります。

public void doSomethingWithBeansInOrder(List<Bean> beans) {
    Collection<Bean> sortedBeans = new ArrayList<Bean>(beans);
    Collections.sort(sortedBeans, ...comparator...;

    for (Bean bean : sortedBeans) {
        .. do something
    }
}

「sortedBeans」の定義は醜いと思います。

"(Collections.sort(..)" (またはそのようなもの) が新しいコレクションを返し、渡されたコレクションに影響を与えない場合、次のように記述できます。

public void doSomethingWithBeansInOrder(List<Bean> beans) {
    for (Bean bean : Collections.sort(beans, ...comparator...) {
        .. do something
    }
}

私の意見では、グアバの答えが最善です。Ordering

于 2014-05-02T16:02:46.443 に答える
1

重複がなく、使用できるハックコードを気にしない場合は、次のようになります。

return new ArrayList<Bean>(new TreeSet<Bean>(service.findBeans()));
于 2013-04-10T22:25:09.707 に答える
1

まず、Java 8 ではインターフェイスにsort()メソッドが導入されましたList。したがって、実際のリストを並べ替える例は次のようになります。

List<Integer> integerList = Arrays.asList(3, 2, 1);
integerList.sort(Comparator.naturalOrder());
return integerList;

ここでは、 ComparablenaturalOrder()に依存する定義済みのコンパレータを使用しましたが、カスタム コンパレータを使用することもできます。これにはまだ 2 つのステートメントが必要です。

ただし、新しいソートされたリストを作成し、元のリストを以前のままにしておくことが望ましい動作である場合は、ストリームが最も簡単な方法であると思います。

integerList.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());

上記と同じことが、ここでのコンパレーターにも当てはまります。

于 2016-12-08T06:56:09.520 に答える