2016-08-15 14 views
15

私にはList<Users>があります。私は特定のユーザー名でストリーム内の(最初の)ユーザーのインデックスを取得したい。私は実際にはUser.equals()と記述して、同じユーザ名を持つように、Userを記述する必要はありません。ストリーム最初の要素のインデックスを取得する方法ブール値

私はこれを行う醜い方法(反復とカウント)を考えることができますが、おそらくStreamsを使用してこれを行う良い方法があるように感じる。これまでのところ、私が持っている最高です:

私が今まで書いてきた最悪のコードではありませんが、それは素晴らしいではありません
int index = users.stream() 
    .map(user -> user.getName()) 
    .collect(Collectors.toList()) 
    .indexOf(username); 

。それは柔軟性がありません。あなたが探しているプロパティを記述する.equals()関数を持つ型へのマッピング関数があることに依存しています。私はむしろ任意のために働くことができる何かを持っているだろうFunction<T, Boolean>

誰か知っている?

+2

です:

これは単純な例ですか? – Andreas

+2

ストリームとインデックスはうまく混合されません。通常、その時点で古いスタイルのループに戻った方が良いでしょう。 –

+1

@Andreasストリームに関して私が気に入っているのは、収集関連のロジックを特定のものから分離することです。この場合、コアの 'Function 'とは異なるだけの質問をすることができますので、一般的なコレクションロジックから抽象化する方法があるはずです。 –

答えて

21

時々、pythonのzipWithIndexはjavaにありません。だから私はそのような何かに出くわした:

OptionalInt indexOpt = IntStream.range(0, users.size()) 
    .filter(i -> searchName.equals(users.get(i))) 
    .findFirst(); 

代わりにあなたはzipWithIndex users.getがない場合は解決に時間がかかる可能性があり注意

ライブラリprotonpackからを使用することができます一定時間動作。

+0

それは動作します。フィルター操作で指定されたインデックスでユーザーを検索するだけで、そのペアをスキップすることもできます。それが良いか悪いかわかりません。 –

+0

@EdwardPeters良い点!私の答えを編集します – vsminkov

+0

@EdwardPetersそれは間違いなく良いです。少なくともそれは追加メモリトラフィックを排除します。 – vsminkov

6

これを試してみてください。

IntStream.range(0, users.size()) 
    .filter(userInd-> users.get(userInd).getName().equals(username)) 
    .findFirst() 
    .get(); 
+0

それは私にユーザーを取得しますが、インデックスはありません –

+0

インデックスを見つけるためにソリューションを更新しました。 – AmanSinghal

+5

希望のユーザーが見つかったか、コードがクラッシュする可能性があります。 – Andreas

4

あなたはTagir Valeevによって作らStreamExライブラリを試すことができます。そのライブラリには便利な#indexOfメソッドがあります。なぜ "反復" *醜い*が

List<User> users = asList(new User("Vas"), new User("Innokenty"), new User("WAT")); 
long index = StreamEx.of(users) 
     .indexOf(user -> user.name.equals("Innokenty")) 
     .getAsLong(); 
System.out.println(index); 
関連する問題