有没有办法递归调用 findMatch ?
Is there a way to call findMatch recursively?
在这个问题中,我需要编写一个 findMatch 方法,该方法接收 "stream"(IFL 旨在模拟流)并找到流中传递谓词的第一个元素。我的尝试如下:
import java.util.function.Predicate;
import java.util.Optional;
import java.util.ArrayList;
import java.util.List;
class IFL<T> {
Supplier<T> head;
Supplier<IFL<T>> tail;
IFL(Supplier<T> head, Supplier<IFL<T>> tail) {
this.head = head;
this.tail = tail;
}
static <T> IFL<T> of(List<? extends T> list) {
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.subList(1, list.size()))) {
};
}
Optional<T> findMatch(Predicate<? super T> predicate) {
if (predicate.test(head.get())) {
return Optional.of(this.head.get());
} else {
if (this.tail.get().findMatch(predicate).isPresent()) {
return this.tail.get().findMatch(predicate);
}
return Optional.empty();
}
}
}
我面临的问题是我的 findMatch 方法中的 else
块似乎只 运行 return
语句,而不是像我认为应该的那样递归调用自身。有没有办法确保它确实如此?
更新:我已经获得了用于第二行输入的代码。但是,运行第三行输入在 jshell 中产生了一个 IndexOutOfBoundsException
。
输入如下
IFL<String> list = IFL.of(Arrays.asList("three", "little", "pigs"))
list.findMatch(str -> str.length() == 6)
list.findMatch(str -> str.length() < 4)
IndexOutOfBoundsException
因 List#subList
方法的非法端点索引值而被抛出 (fromIndex < 0 || toIndex > size || fromIndex > toIndex)
在您的 IFL#of
方法中,您需要检查给定列表的大小是否为 1。如果是,请将 tail
设置为空列表。
static <T> IFL<T> of(List<? extends T> list) {
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.size == 1 ? new ArrayList<T>() : list.subList(1, list.size()))) {
};
试试下面的代码
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.Optional;
import java.util.List;
import java.util.function.Supplier;
class IFL<T> {
Supplier<T> head;
Supplier<IFL<T>> tail;
List<? extends T> list;
IFL(Supplier<T> head, Supplier<IFL<T>> tail, List<? extends T> list) {
this.head = head;
this.tail = tail;
this.list = list;
}
static <T> IFL<T> of(List<? extends T> list) {
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.subList(1, list.size())), list) {
};
}
Optional<T> findMatch(Predicate<? super T> predicate) {
if (!list.isEmpty() && predicate.test(head.get())) {
return Optional.of(this.head.get());
} else {
if (!list.isEmpty() && this.tail.get().findMatch(predicate).isPresent()) {
return this.tail.get().findMatch(predicate);
}
return Optional.empty();
}
}
public static void main(String...args) {
IFL<String> list = IFL.of(Arrays.asList("three", "little", "pigs"));
System.out.println(list.findMatch(str -> str.length() == 6));
System.out.println(list.findMatch(str -> str.length() < 4));
}
}
希望这对您有所帮助!!!
你可以这样做:
通过检查构造函数中的列表大小并在 findMatch()
方法中检查 this.head
的无效性;
您不需要检查 if (this.tail.get().findMatch(predicate).isPresent())
然后再次调用 findMatch
方法。
class IFL<T> {
Supplier<T> head;
Supplier<IFL<T>> tail;
IFL(Supplier<T> head, Supplier<IFL<T>> tail) {
this.head = head;
this.tail = tail;
}
static <T> IFL<T> of(List<? extends T> list) {
if (list.isEmpty())
return new IFL<>(null, null);
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.subList(1, list.size()))) {
};
}
Optional<T> findMatch(Predicate<? super T> predicate) {
if (this.head == null)
return Optional.empty();
return predicate.test(head.get()) ?
Optional.of(this.head.get()) :this.tail.get().findMatch(predicate);
}
}
在这个问题中,我需要编写一个 findMatch 方法,该方法接收 "stream"(IFL 旨在模拟流)并找到流中传递谓词的第一个元素。我的尝试如下:
import java.util.function.Predicate;
import java.util.Optional;
import java.util.ArrayList;
import java.util.List;
class IFL<T> {
Supplier<T> head;
Supplier<IFL<T>> tail;
IFL(Supplier<T> head, Supplier<IFL<T>> tail) {
this.head = head;
this.tail = tail;
}
static <T> IFL<T> of(List<? extends T> list) {
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.subList(1, list.size()))) {
};
}
Optional<T> findMatch(Predicate<? super T> predicate) {
if (predicate.test(head.get())) {
return Optional.of(this.head.get());
} else {
if (this.tail.get().findMatch(predicate).isPresent()) {
return this.tail.get().findMatch(predicate);
}
return Optional.empty();
}
}
}
我面临的问题是我的 findMatch 方法中的 else
块似乎只 运行 return
语句,而不是像我认为应该的那样递归调用自身。有没有办法确保它确实如此?
更新:我已经获得了用于第二行输入的代码。但是,运行第三行输入在 jshell 中产生了一个 IndexOutOfBoundsException
。
输入如下
IFL<String> list = IFL.of(Arrays.asList("three", "little", "pigs"))
list.findMatch(str -> str.length() == 6)
list.findMatch(str -> str.length() < 4)
IndexOutOfBoundsException
因 List#subList
方法的非法端点索引值而被抛出 (fromIndex < 0 || toIndex > size || fromIndex > toIndex)
在您的 IFL#of
方法中,您需要检查给定列表的大小是否为 1。如果是,请将 tail
设置为空列表。
static <T> IFL<T> of(List<? extends T> list) {
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.size == 1 ? new ArrayList<T>() : list.subList(1, list.size()))) {
};
试试下面的代码
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.Optional;
import java.util.List;
import java.util.function.Supplier;
class IFL<T> {
Supplier<T> head;
Supplier<IFL<T>> tail;
List<? extends T> list;
IFL(Supplier<T> head, Supplier<IFL<T>> tail, List<? extends T> list) {
this.head = head;
this.tail = tail;
this.list = list;
}
static <T> IFL<T> of(List<? extends T> list) {
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.subList(1, list.size())), list) {
};
}
Optional<T> findMatch(Predicate<? super T> predicate) {
if (!list.isEmpty() && predicate.test(head.get())) {
return Optional.of(this.head.get());
} else {
if (!list.isEmpty() && this.tail.get().findMatch(predicate).isPresent()) {
return this.tail.get().findMatch(predicate);
}
return Optional.empty();
}
}
public static void main(String...args) {
IFL<String> list = IFL.of(Arrays.asList("three", "little", "pigs"));
System.out.println(list.findMatch(str -> str.length() == 6));
System.out.println(list.findMatch(str -> str.length() < 4));
}
}
希望这对您有所帮助!!!
你可以这样做:
通过检查构造函数中的列表大小并在 findMatch()
方法中检查 this.head
的无效性;
您不需要检查 if (this.tail.get().findMatch(predicate).isPresent())
然后再次调用 findMatch
方法。
class IFL<T> {
Supplier<T> head;
Supplier<IFL<T>> tail;
IFL(Supplier<T> head, Supplier<IFL<T>> tail) {
this.head = head;
this.tail = tail;
}
static <T> IFL<T> of(List<? extends T> list) {
if (list.isEmpty())
return new IFL<>(null, null);
return new IFL<T>(
() -> list.get(0),
() -> IFL.of(list.subList(1, list.size()))) {
};
}
Optional<T> findMatch(Predicate<? super T> predicate) {
if (this.head == null)
return Optional.empty();
return predicate.test(head.get()) ?
Optional.of(this.head.get()) :this.tail.get().findMatch(predicate);
}
}