如何修復此代碼塊(在ifPresentOrElse()
)?
我被困在這里:
Inconvertible types; cannot cast '<lambda parameter>' to 'char'
請告知如何編譯和運行它。
public static boolean isBracketsInOrder1(String bracket) {
Stack<Character> charStack = new Stack<>();
static Map<Character, Character> leftToRightBracketsMap =
Map.of('{', '}', '[', ']', '(', ')');
bracket.chars()
.filter(i -> leftToRightBracketsMap.containsKey((char) i))
.findFirst()
.ifPresentOrElse((i) -> charStack.push((char) i),
(i) -> {
// code does not COMPILE at equals((char) i)
return leftToRightBracketsMap.get(charStack.pop()).equals((char) i);
});
return true;
}
這是使用for
回圈的作業代碼,表示我使用上面的流在上面嘗試實作的內容。
public static boolean isBracketsInOrder(String bracket) {
Stack<Character> charStack = new Stack<>();
static Map<Character, Character> leftToRightBracketsMap =
Map.of('{', '}', '[', ']', '(', ')');
boolean matchFound = true;
for (char c : bracket.toCharArray()) {
if (leftToRightBracketsMap.containsKey(c)) charStack.push(c);
else {
char leftBrack = charStack.pop();
char correctBrack = leftToRightBracketsMap.get(leftBrack);
if (c != correctBrack) return false;
}
}
return true;
}
uj5u.com熱心網友回復:
您已經介紹了一個非常基本的演算法問題的代碼 -驗證一串括號。
您的代碼中有很多錯誤:
流的行為與回圈不同,當它遇到終端操作(
findFirst()
在您的代碼中)時,它就完成了。里面的代碼ifPresentOrElse()
不會被多次執行(你可能期望相反)。它只會在回傳的可選結果上被呼叫一次findFirst()
。因為它的第二個引數
ifPresentOrElse()
需要一個介面實體Runnable
。方法run()
既不期望任何引數,也不回傳值。因此,這種定義 a 的嘗試Runnable
是不正確的:(i) -> { return something; }
.任何lambda 運算式都應該符合特定的功能介面(請參閱 參考資料)。它不能憑空出現。
類
Stack
是遺留的,出于向后兼容性的原因,它仍然在 JDK 中。Deque
應改為使用介面的實作。您沒有檢查堆疊是否為空,這可能會導致
EmptyStackException
. 如果您將替換為Stack
問題ArrayDeque
仍然存在,方法pop()
將拋出NoSuchElementException
。您需要確保堆疊不為空。在命令式解決方案中回傳
true
是不正確的。相反,您需要 returncharStack.isEmpty()
,因為如果堆疊中有一些元素 - 序列無效,則有括號尚未關閉。
使用流實作這個問題比使用普通回圈的解決方案需要更多的努力。
根據檔案,流中唯一可能發生突變的地方是收集器內部。作為一般規則,流管道中使用的所有函式都不應通過副作用操作并在流外部累積宣告(除了一些邊緣情況,請參閱鏈接)。只有收集器的可變容器應該保持狀態。
我們可以使用Collecor.of()
以下方法收縮這樣的收集器:
public static boolean isValidBracketSequence(String brackets) {
return brackets.chars()
.mapToObj(c -> (char) c)
.collect(getBracketCollector());
}
public static Collector<Character, ?, Boolean> getBracketCollector() {
return Collector.of(
BracketContainer::new,
BracketContainer::add,
(left, right) -> { throw new AssertionError("should not be executed in parallel"); },
bracketContainer -> bracketContainer.isValid() && bracketContainer.isEmpty()
);
}
這就是可變容器的樣子:
class BracketContainer {
public static final Map<Character, Character> leftToRightBracketsMap =
Map.of('(', ')', '[', ']', '{', '}');
private Deque<Character> stack = new ArrayDeque<>();
private boolean isValid = true;
public void add(Character next) {
if (!isValid) return;
if (leftToRightBracketsMap.containsKey(next)) {
stack.push(next);
} else {
compare(next);
}
}
public void compare(Character next) {
this.isValid = !isEmpty() && leftToRightBracketsMap.get(stack.pop()).equals(next);
}
public boolean isEmpty() {
return stack.isEmpty();
}
public boolean isValid() {
return isValid;
}
}
main()
public static void main(String[] args) {
System.out.println("(([])) -> " isValidBracketSequence("(([]))")); // true
System.out.println("(([]]) -> " isValidBracketSequence("(([]])")); // false
System.out.println("(([})) -> " isValidBracketSequence("(([}))")); // false
System.out.println("({[])) -> " isValidBracketSequence("({[]))")); // false
System.out.println("({[]}) -> " isValidBracketSequence("({[]})")); // true
}
輸出:
(([])) -> true
(([]]) -> false
(([})) -> false
({[])) -> false
({[]}) -> true
在線演示的鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/491065.html
上一篇:Python:為什么在for回圈中添加到集合會終止?
下一篇:質數檢查不起作用