次のようなforeach
ループがあると仮定します。
Set<String> names = new HashSet<>();
//some code
for (String name: names) {
//some code
}
foreach
の内部で、実際の名前がSet
の最後の名前であることをカウンターなしで確認する方法はありますか?
(質問が重複している場合は申し訳ありませんが、このような質問はここでは見つかりませんでした)
ありません。 Java 'for each'ループはどのように機能しますか?
イテレータを明示的に使用するか、intカウンタを使用するには、ループを変更する必要があります。
シンプルでわかりやすくするために、imoは次のことを行います。
Set<String> names = new HashSet<>();
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String name = iterator.next();
//Do stuff
if (!iterator.hasNext()) {
//last name
}
}
また、何を達成しようとしているかにもよります。各名前をコマで区切る一般的なユースケースを実装しているが、最後に空のコマを追加しないとしましょう:
Set<String> names = new HashSet<>();
names.add("Joao");
names.add("Pereira");
//if the result should be Joao, Pereira then something like this may work
String result = names.stream().collect(Collectors.joining(", "));
特定の質問に対してこのソリューションを追加するだけで、他の回答も完全に適切です。
Set<String> names = new HashSet<>();
//some code
int i = 0;
for (String name: names) {
if(i++ == names.size() - 1){
// Last iteration
}
//some code
}
HashSetには既にString値が含まれているため、上記の答えの.map(String :: toString)は冗長です。順序が保証されないため、Setを使用して文字列を連結しないでください。
List<String> nameList = Arrays.asList("Michael", "Kate", "Tom");
String result = nameList.stream().collect(Collectors.joining(", "));
単純なリスト/セットだけでなく、複雑なオブジェクトを使用している場合は、次のコードが役立ちます。収集する前に、実際に目的の文字列を取得するマップ関数を追加するだけです。
String result = violations.stream().map(e->e.getMessage()).collect(Collectors.joining(", "));
現在の要素が最後の要素でもあるかどうかを確認するための組み込みメソッドはありません。それに加えて、戻り順序を保証しないHashSet
を使用しています。確認したい場合でもインデックスi
を使用すると、最後の要素は常に別の要素になる可能性があります。
Set
は、その中のアイテムの順序を保証しません。 Set
を1回ループして「abc」を「最後のアイテム」として取得し、次に「hij」がSet
の「最後のアイテム」であることがわかります。
そうは言っても、順序を気にせず、その瞬間にSet
を観察するときに任意の「最後の項目」が何であるかを知りたいだけの場合、これを行う方法はありません。カウンターを使用する必要があります。