Am正在编写线性搜索实现。我也使用Java 7和8编写了代码。
下面是我的代码:
int[] arr = new int[] { 12, 34, 94, 8, 37, 10 };
System.out.println("Enter the element to search: ");
Scanner scan = new Scanner(System.in);
int element = scan.nextInt();
boolean found = false;
// Linear search implementation using Java 7 features
for (int i = 0; i < arr.length; i++) {
if (element == arr[i]) {
int n = element;
System.out.println("Element : "+n+" has been found at the index : "+i);
found = true;
break;
}
}
// Linear search implementation using Java 8 features
IntStream.range(0, arr.length)
.forEach(i -> {
if (element == arr[i]) {
int n = element;
System.out.println("Element : " + n + " has been found at the index : " + i);
found = true;
break;
}
});
if (!found) {
System.out.println("Element : "+ element + " not found.");
}
以下代码正常工作:
for (int i = 0; i < arr.length; i++) {
if (element == arr[i]) {
int n = element;
System.out.println("Element : " + n + " has been found at the index : " + i);
found = true;
break;
}
}
但是,下面具有Java 8功能的代码为forEach循环内的字段抛出错误
IntStream.range(0, arr.length)
.forEach(i -> {
if (element == arr[i]) {
int n = element;
System.out.println("Element : " + n + " has been found at the index : " + i);
found = true;
break;
}
});
发生错误:
在封闭范围内定义的局部变量必须是最终的或实际上是最终的
break不能在循环或开关之外使用
如何在Java 8功能的forEach块中访问boolean found
?
答案 0 :(得分:5)
实际上该消息已经说明了。请注意,在使用流时,通常会尝试避免使用.forEach
(或者至少不只是将for
循环转换为.forEach
)。
您可能想要的是以下内容:
IntStream.range(0, arr.length)
.filter(i -> element == arr[i]) // .equals( ??
.findFirst()
.ifPresent(i -> System.out.println("Element : "+element+" has been found at the index : "+i));
如果您还必须处理找不到的情况,请使用以下命令:
OptionalInt result = IntStream.range(0, arr.length)
.filter(i -> element == arr[i]) // .equals( ??
.findFirst();
if (result.isPresent()) {
System.out.printf("Element : %s has been found at the index : %d%n", element, result.getAsInt());
} else {
// none found
System.out.printf("Element %s not found%n", element);
}
较新的Java版本支持ifPresentOrElse
,例如在此处可能有用。 (由MC Emperor测试的代码,因为我在这里没有Java> 8;-)):
...
.findFirst()
.ifPresentOrElse(i -> System.out.printf("Element : %s has been found at the index : %d%n", element, i),
() -> System.out.printf("Element %s not found%n", element));
答案 1 :(得分:1)
您不应访问boolean found
,而应从流中返回该值。
int element;
OptionalInt valueOptional = Arrays.stream(arr)
.filter(current -> current == element)
.findFirst();
然后,检查天气是否存在可选项。
valueOptional.isPresent();
答案 2 :(得分:1)
有多种方法可以执行此操作,具体取决于您的具体要求:
您当然可以创建一个包含给定数组的所有索引的IntStream.range(0, arr.length)
:
element
然后您可以检查给定位置的元素是否等于 .filter(i -> arr[i] == element)
:
element
如果发现任何等于 .findAny()
的数组元素,我们可以中止步行:
OptionalInt
这将返回一个OptionalInt
,其中包含找到的元素的第一个索引。 -1
设计为包含值或不包含值。这比使用哨兵值(例如 .ifPresent(i -> System.out.println("Element " + element + " found at index " + i))
)更好。
如果找到该值,则可以执行某些操作:
Arrays
如果您不关心实际索引,也可以直接流式处理数组。 java.util
包中的int[]
类提供了一种流int
并返回IntStream的方法,该流是设计用来流Arrays.stream(arr)
.filter(t -> t == element)
.findAny()
.ifPresent(t -> ...);
的源的流。>
Arrays.stream(arr).findAny()
流元素被延迟消耗。这意味着如果消耗了足够的元素以达到最终结果,则流终止。例如,arr
仅触摸findAny()
的第一个元素。您可以说if (found) { break; }
的作用类似于forEach
。
请注意,您实际上正在使用lambda expression。那是Java 8中引入的一种新的语言构造。Consumer
只不过是接受forEach
的方法,而该方法又是functional interface。您只能access variables which are final
or effectively final。 for
方法不同于break
循环,因此您实际上不能使用function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.min.js", function(){
//initialization code
alert('loaded: ' + faker.name.findName());
});
。