英文:
Return the index of the first item in generics collections
问题
/**
* 返回满足 aPredicate.test(o) 条件的第一个元素在 someCollection 中的索引,如果没有则返回 -1。
*/
public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
List<T> list = new ArrayList<>();
for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext(); ) {
T value = iterator.next();
if (aPredicate.test(value)) {
list.add(value);
}
}
return list.indexOf(list.get(0)); // 或者直接返回 list.indexOf(list.get(0))
}
// 对于只适用于整数集合的情况,如何返回第一个元素的索引呢?
英文:
/**
* Return the index of the first item in someCollection for which * aPredicate.test(o) is true, or -1.
*/
public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
List<T> list = new ArrayList<>();
for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext(); ) {
T value = iterator.next();
if (aPredicate.test(value)) {
list.add(value);
}
}
return list[0]; // or return list.get(0)
}
With the code above, I cannot use list[0] since it needs to be replaced with list.get(0), but this method is only applicable to the collection of Integers.
How can I return the index of the first element in such case?
答案1
得分: 1
你的函数目的是返回与给定的“Predicate”匹配的“Collection”中第一个元素的索引。因此,你应该存储一个List<int>
而不是一个List<T>
,如果要返回找到的第一个元素,根本没有存储列表的必要。因此,完全移除缓冲列表,在找到匹配的元素后立即返回。
public static int find(Collection<?> someCollection, Predicate<?> aPredicate) {
int index = 0;
for (Iterator<?> iterator = someCollection.iterator(); iterator.hasNext(); ) {
Object value = iterator.next();
if (aPredicate.test(value)) {
return index;
}
index++;
}
return -1;
}
英文:
The purpose of your function is to return the first index of the first element in a Collection
that matches the given Predicate
. As such, not only should you be storing a List<int>
rather than a List<T>
, there's no reason to be storing a list at all if the point is to return the first thing found. As such, remove the buffer list entirely and return as soon as you find a matching element.
public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
// Collections don't necessarily natively support indices, so you must
// manually track the current index
int index = 0;
for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext(); ) {
T value = iterator.next();
if (aPredicate.test(value)) {
// A matching element was found, so there's no point continuing to loop
return index;
}
index++;
}
// No element was found, so return the conventional -1
return -1;
}
答案2
得分: 0
你想要的不是存储 List<T>
,而是一个 List<Integer>
,基本上,它包含了你找到的元素的索引。你将不得不自己跟踪该索引,以及追踪调用了多少次 iterator.next()
。
英文:
What you want isn't to store a List<T>
, but a List<Integer>
, essentially, containing the index of the elements you found. You will have to track that index yourself, but tracking how many calls to iterator.next()
you have made.
答案3
得分: 0
让我们首先确保您的方法执行正确的操作:
public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
int i = -1;
for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext();) {
++i;
T value = iterator.next();
if (aPredicate.test(value)) {
return i;
}
}
return -1;
}
让我们看看它是否有效:
public static void main(String[] args) {
List<Integer> list = List.of(1, 2, 3);
System.out.println(find(list, x -> x == 4)); // -1
System.out.println(find(list, x -> x == 2)); // 1
}
虽然它能正常工作,但它是否正确呢?...
public static void main(String[] args) {
Set<String> set = Set.of("abc", "ade");
System.out.println(find(set, "abc"::equals));
}
多次运行此代码(使用 Java 9),您会惊讶地发现索引会发生变化。Set
没有任何顺序,而在 Java 9 中添加的不可变集合在创建时会进行一些内部随机化,因此结果可能会完全不正确。想要更广泛的了解,可以查看这里。
您可能会认为 Java 有一个通用的接口,用于确定特定集合是否有序,但实际上并没有。因此,除了重新考虑您想要做的事情之外,您真的无法做太多事情,也许会有所帮助。
英文:
Let's first make sure your method does the correct thing:
public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
int i = -1;
for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext();) {
++i;
T value = iterator.next();
if (aPredicate.test(value)) {
return i;
}
}
return -1;
}
Let's see if it works:
public static void main(String[] args) {
List<Integer> list = List.of(1, 2, 3);
System.out.println(find(list, x -> x == 4)); // -1
System.out.println(find(list, x -> x == 2)); // 1
}
It does, but is it correct?...
public static void main(String[] args) {
Set<String> set = Set.of("abc", "ade");
System.out.println(find(set, "abc"::equals));
}
Run this a few times (with java-9) and be surprised how the index will change. A Set
does not have any order and immutable collections added in java-9 do some internal randomization when they are first created, so the results might get entirely incorrect. For a broader read, look here.
You could think that java has a common interface for when a certain Collection would be ordered or not, but it does not. So you can't really do much, other then rethink what you want to do, may be.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论