我有以下Java代码,但List.indexOf()似乎做了几乎相同的事情(包括如果没有找到则返回-1。有没有办法传递indexOf()一个表达这个想法的对象对象不是0?
/**
* Find the first non-zero element in a List of Integers
* @param row List of Integers
* @return -1 if all zeros in row
* otherwise position of first non zero element
*/
public static int leading(List<Integer> row) {
for (int i = 0; i < row.size(); i++) {
if (row.get(i)!= 0) {
return i;
}
}
return -1;
}
Re:ThorbjørnRavnAndersen:如果我将null传入IndexOf(),它将始终返回-1,因为我的列表总是包含整数。我想做一些像row.indexOf(Integer a where!a.equals(0))的东西。不确定是否可能
答案 0 :(得分:6)
List.indexOf
“解决方案”返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回
-1
。更正式地,返回最低索引i
,使(o==null ? get(i)==null : o.equals(get(i)))
是
true
,如果没有这样的索引,则为-1
。
尝试提供一个实际上不在List
中的“meta”元素对象很有诱惑力,甚至可能与List
的实际元素的类型不同,并且然而equals
是基于谓词的某个所需元素。这应该有效,因为indexOf
是根据给定Object o
的{{1}}方法针对列表中的元素定义的(而不是相反),但实际上是“ hacky“实现你想要的方式。
以下是概念证明:
equals
“meta”元素对象// PROOF OF CONCEPT ONLY! DO NOT IMITATE!
// abusing indexOf(Object) to find index of a negative integer in List
List<Integer> nums = Arrays.asList(3,4,5,-6,7);
Object equalsNegativeInteger = new Object() {
@Override public boolean equals(Object o) {
return (o instanceof Integer) && ((Integer) o) < 0;
}
};
System.out.println(nums.indexOf(equalsNegativeInteger));
// prints 3
对任何否定equals
,但Integer
对Integer
不能equals
。这种不对称严重违反了the equals
contract,但它“仍然有效”。
传达意图的更好的解决方案是使用Guava的高阶函数。这是com.google.commons.collect.Iterables
中的一个:
<T> int indexOf(Iterable<T> iterable, Predicate<? super T> predicate)
返回满足所提供谓词的第一个元素的iterable中的索引,如果
-1
没有这样的元素,则返回Iterable
。更正式地,返回最低索引i
,使得:predicate.apply(Iterables.get(iterable, i))
是
true
,如果没有这样的索引,则为-1
。
这里有一个片段来说明番石榴高阶函数的表达能力:
import com.google.common.collect.*;
import com.google.common.base.*;
import java.util.*;
public class IterablesPredicateExample {
public static void main(String[] args) {
List<Integer> nums = Arrays.asList(1,2,-3,4,-5,6,-7,-8);
Predicate<Integer> isNegative = new Predicate<Integer>() {
@Override public boolean apply(Integer n) {
return n < 0;
}
};
// Get index of first negative number
System.out.println(Iterables.indexOf(nums, isNegative));
// 2
// Find that number
System.out.println(Iterables.find(nums, isNegative));
// -3
// Find all negative numbers
System.out.println(Iterables.filter(nums, isNegative));
// [-3, -5, -7, -8]
// Are all numbers negative?
System.out.println(Iterables.all(nums, isNegative));
// false
// Find all non-negative numbers
System.out.println(Iterables.filter(nums, Predicates.not(isNegative)));
// [1, 2, 4, 6]
}
}
List.indexOf(Object)
来查找满足给定谓词的元素,但这违反了equals
合同Predicate
及更高阶函数,例如indexOf
,find
,filter
,all
,any
等,可让您表达这些操作以更有力的表达方式答案 1 :(得分:1)
List.indexOf(Object)
方法将返回找到指定Object
的第一个索引。
问题中给出的代码似乎具有以下要求:
0
的第一个索引。-1
。不幸的是,无法使用indexOf
方法表达上述内容。
因此,您提供的代码似乎是可接受的要求实现。
答案 2 :(得分:0)
不,java不支持闭包。
标准的解决方法是使用匿名内部类,但这需要足够的样板代码来使解决方案变得复杂,因为实现了该循环。
答案 3 :(得分:-1)
我不相信标准运行时库中存在这样的方法。
问题是你是否需要这么多,以便记录非零值,或者你可以用暴力搜索。我会使用后者,并跟踪System.currentMillis()之间的区别,如果它超过了您决定的限制,请记录它。然后,您不必运行探查器来查找已知的可能瓶颈。
另请注意,您在样本中进行自动装箱。这种开销可能是不必要的。