返回泛型集合中第一个项目的索引

huangapple go评论139阅读模式
英文:

Return the index of the first item in generics collections

问题

  1. /**
  2. * 返回满足 aPredicate.test(o) 条件的第一个元素在 someCollection 中的索引,如果没有则返回 -1。
  3. */
  4. public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
  5. List<T> list = new ArrayList<>();
  6. for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext(); ) {
  7. T value = iterator.next();
  8. if (aPredicate.test(value)) {
  9. list.add(value);
  10. }
  11. }
  12. return list.indexOf(list.get(0)); // 或者直接返回 list.indexOf(list.get(0))
  13. }
  14. // 对于只适用于整数集合的情况,如何返回第一个元素的索引呢?
英文:
  1. /**
  2. * Return the index of the first item in someCollection for which * aPredicate.test(o) is true, or -1.
  3. */
  4. public static &lt;T&gt; int find(Collection&lt;T&gt; someCollection, Predicate&lt;T&gt; aPredicate) {
  5. List&lt;T&gt; list = new ArrayList&lt;&gt;();
  6. for (Iterator&lt;T&gt; iterator = someCollection.iterator(); iterator.hasNext(); ) {
  7. T value = iterator.next();
  8. if (aPredicate.test(value)) {
  9. list.add(value);
  10. }
  11. }
  12. return list[0]; // or return list.get(0)
  13. }

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>,如果要返回找到的第一个元素,根本没有存储列表的必要。因此,完全移除缓冲列表,在找到匹配的元素后立即返回。

  1. public static int find(Collection<?> someCollection, Predicate<?> aPredicate) {
  2. int index = 0;
  3. for (Iterator<?> iterator = someCollection.iterator(); iterator.hasNext(); ) {
  4. Object value = iterator.next();
  5. if (aPredicate.test(value)) {
  6. return index;
  7. }
  8. index++;
  9. }
  10. return -1;
  11. }
英文:

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&lt;int&gt; rather than a List&lt;T&gt;, 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.

  1. public static &lt;T&gt; int find(Collection&lt;T&gt; someCollection, Predicate&lt;T&gt; aPredicate) {
  2. // Collections don&#39;t necessarily natively support indices, so you must
  3. // manually track the current index
  4. int index = 0;
  5. for (Iterator&lt;T&gt; iterator = someCollection.iterator(); iterator.hasNext(); ) {
  6. T value = iterator.next();
  7. if (aPredicate.test(value)) {
  8. // A matching element was found, so there&#39;s no point continuing to loop
  9. return index;
  10. }
  11. index++;
  12. }
  13. // No element was found, so return the conventional -1
  14. return -1;
  15. }

答案2

得分: 0

你想要的不是存储 List<T>,而是一个 List<Integer>,基本上,它包含了你找到的元素的索引。你将不得不自己跟踪该索引,以及追踪调用了多少次 iterator.next()

英文:

What you want isn't to store a List&lt;T&gt;, but a List&lt;Integer&gt;, 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

让我们首先确保您的方法执行正确的操作:

  1. public static <T> int find(Collection<T> someCollection, Predicate<T> aPredicate) {
  2. int i = -1;
  3. for (Iterator<T> iterator = someCollection.iterator(); iterator.hasNext();) {
  4. ++i;
  5. T value = iterator.next();
  6. if (aPredicate.test(value)) {
  7. return i;
  8. }
  9. }
  10. return -1;
  11. }

让我们看看它是否有效:

  1. public static void main(String[] args) {
  2. List<Integer> list = List.of(1, 2, 3);
  3. System.out.println(find(list, x -> x == 4)); // -1
  4. System.out.println(find(list, x -> x == 2)); // 1
  5. }

虽然它能正常工作,但它是否正确呢?...

  1. public static void main(String[] args) {
  2. Set<String> set = Set.of("abc", "ade");
  3. System.out.println(find(set, "abc"::equals));
  4. }

多次运行此代码(使用 Java 9),您会惊讶地发现索引会发生变化。Set 没有任何顺序,而在 Java 9 中添加的不可变集合在创建时会进行一些内部随机化,因此结果可能会完全不正确。想要更广泛的了解,可以查看这里

您可能会认为 Java 有一个通用的接口,用于确定特定集合是否有序,但实际上并没有。因此,除了重新考虑您想要做的事情之外,您真的无法做太多事情,也许会有所帮助。

英文:

Let's first make sure your method does the correct thing:

  1. public static &lt;T&gt; int find(Collection&lt;T&gt; someCollection, Predicate&lt;T&gt; aPredicate) {
  2. int i = -1;
  3. for (Iterator&lt;T&gt; iterator = someCollection.iterator(); iterator.hasNext();) {
  4. ++i;
  5. T value = iterator.next();
  6. if (aPredicate.test(value)) {
  7. return i;
  8. }
  9. }
  10. return -1;
  11. }

Let's see if it works:

  1. public static void main(String[] args) {
  2. List&lt;Integer&gt; list = List.of(1, 2, 3);
  3. System.out.println(find(list, x -&gt; x == 4)); // -1
  4. System.out.println(find(list, x -&gt; x == 2)); // 1
  5. }

It does, but is it correct?...

  1. public static void main(String[] args) {
  2. Set&lt;String&gt; set = Set.of(&quot;abc&quot;, &quot;ade&quot;);
  3. System.out.println(find(set, &quot;abc&quot;::equals));
  4. }

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.

huangapple
  • 本文由 发表于 2020年10月22日 00:58:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/64468305.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定