debugging 赋值给变量时布尔值会发生变化- java

beq87vna  于 2023-06-06  发布在  Java
关注(0)|答案(2)|浏览(151)

我正在对行(String)进行标记化。
我必须对这一行进行标记化。
class Main {转换为[ "class" , "Main", "{" ]
这个过程就像是我把一些条件变量化了,比如boolean conditionA = (isSpace && isSymbol)
在for循环中,我检查行中的一个字符。在上面的示例中,如检查cla。等等。
问题来了。
我做了一个布尔变量

private static boolean isTailWhiteSpace = 
Character.isWhitespace(currentChar) && !tempWord.isEmpty();

currentChar中的Character.isWhitespace(currentChar)class Main {class旁边的空格
因为currentChar现在持有一个空格值,所以isWhiteSpace为true。
tempWord中的!tempWord.isEmpty()class,因此tempWord包含"class"
此外,tempWord现在保存"class",因此值为!false。所以true
我希望它们的值是true && true。因此,变量也保存这些结果true
但它没有像我预期的那样工作。
因为我不相信我自己在电脑上,所以我检查了调试器。

和isTailwhiteSpace的声明。

isTailWhiteSpace怎么会是false呢?
我也检查了可能的副作用,但isTailWhiteSpace只使用一次,从未重新声明。
更多信息,这是上面代码if语句的用法,

else if(isTailWhiteSpace){
    tokenizedLine.add(tempWord);
    tempWord = "";
}

这是可复制的代码。

import java.util.ArrayList;
import java.util.Arrays;

class BooleanDemo {
    private static String tempWord = "";
    private static char currentChar;
    private static boolean isTailWhiteSpace = Character.isWhitespace(currentChar) && !tempWord.isEmpty();

    //Just for symbol checking
    private static final Character[] symbols = {
            '(', ')', '{', '}', '[', ']', '.', ',', ';', '+', '-', '*', '/', '|', '&', '<', '>', '=', '~'
    };
    private static final ArrayList<Character> symbolList = new ArrayList<>(Arrays.asList(symbols));
    private static boolean isSymbol = symbolList.contains(currentChar);

    public static ArrayList<String> tokenize(String line){
        ArrayList<String> tokenizedLine = new ArrayList<>();

        for(char c : line.toCharArray()){
            currentChar = c;
            if(isTailWhiteSpace){
                tokenizedLine.add(tempWord);
                tempWord = "";
            }else if(!isSymbol){
                tempWord += currentChar;
            }else{
                System.out.println("else");
            }
        }
        
        return tokenizedLine;
    }

    public static void main(String[] args){
        String sampleLine = "class Main {";

        System.out.println(BooleanDemo.tokenize(sampleLine));
        //Expected Result = ["class", "Main", "{"]
    }
}
1l5u6lss

1l5u6lss1#

在初始化之后,您没有在代码中动态刷新isTailWhiteSpace的值

private static boolean isTailWhiteSpace = Character.isWhitespace(currentChar) && !tempWord.isEmpty();

isTailWhiteSpace = true && false;

你能理解这段代码吗:

String a = "";
boolean b = true && a.isEmpty();
a = "abc";
System.out.println(b); // I think, although the value of a has changed, but b is still true

每当tempWord发生变化时,都需要重新计算isTailWhiteSpace的值。如果我给予a和B为例,应该是这样的:

String a = "";
boolean b = true && a.isEmpty();
System.out.println(b); // b is true
a = "abc";
System.out.println(b); // I think, although the value of a has changed, but b is still true
b = true && a.isEmpty();
System.out.println(b); // now, b is false

在您的代码中:

if(isTailWhiteSpace){
    tokenizedLine.add(tempWord);
    tempWord = "";
    // here, tempWord changed, you need to recalculate
}else if(!isSymbol){
    tempWord += currentChar;
    // here, tempWord changed, you need to recalculate
}else{
    System.out.println("else");
}

工作,时间不多,可以自己处理细节,也可以提取方法计算isTailWhiteSpace

c3frrgcw

c3frrgcw2#

您正在寻找的概念是一个过程,而不是一个任务。
例如,您将按如下方式分配变量。

private static boolean isTailWhiteSpace = 
    Character.isWhitespace(currentChar) && !tempWord.isEmpty();

我想,你是假设每当你调用 isTailWhiteSpace,它将运行赋值语句。
换句话说,currentChar 将是不同的值。
这里要查找的是一个过程,Java将其称为 * methods *。

private static boolean isTailWhiteSpace() {
    return Character.isWhitespace(currentChar) && !tempWord.isEmpty();
}

此外,可以减少条件语句。
如果Character.isWhitespace(currentChar)表达式返回true,那么!tempWord.isEmpty()将因此为true。

  • String#isEmpty* 方法只是输入string.length == 0的一种更快的方法。

事实上,如果您查看 isEmpty 的源代码,您会发现这就是它执行的确切语句。

@Override
public boolean isEmpty() {
    return value.length == 0;
}

同样,isSymbol 语句在代码中解析时也不会执行其赋值。
您还必须将其更改为方法。

private static boolean isSymbol() {
    return symbolList.contains(currentChar);
}

由于现在有了方法,请确保在它们的用法上附加左括号和右括号。
最后,要派生一个也包含 symbols 字符的列表,您需要在for循环中使用一个新的 else-if 条件。
我不知道在哪里需要 “else”println,所以我把它添加到appending块中。

for(char c : line.toCharArray()){
    currentChar = c;
    if(isTailWhiteSpace()) {
        tokenizedLine.add(tempWord);
        tempWord = "";
    } else if (isSymbol()) {
        tokenizedLine.add(String.valueOf(currentChar));
    }else {
        System.out.println("else");
        tempWord += currentChar;
    }
}

因此,总的来说,您的代码将如下所示。

private static String tempWord = "";
private static char currentChar;

private static boolean isTailWhiteSpace() {
    return Character.isWhitespace(currentChar);
}

//Just for symbol checking
private static final Character[] symbols = {
    '(', ')', '{', '}', '[', ']', '.', ',', ';', '+', '-', '*', '/', '|', '&', '<', '>', '=', '~'
};
private static final ArrayList<Character> symbolList = new ArrayList<>(Arrays.asList(symbols));

private static boolean isSymbol() {
    return symbolList.contains(currentChar);
}

public static ArrayList<String> tokenize(String line){
    ArrayList<String> tokenizedLine = new ArrayList<>();

    for(char c : line.toCharArray()){
        currentChar = c;
        if(isTailWhiteSpace()) {
            tokenizedLine.add(tempWord);
            tempWord = "";
        } else if (isSymbol()) {
            tokenizedLine.add(String.valueOf(currentChar));
        }else {
            System.out.println("else");
            tempWord += currentChar;
        }
    }

    return tokenizedLine;
}

public static void main(String[] args){
    String sampleLine = "class Main {";

    System.out.println(BooleanDemo.tokenize(sampleLine));
    //Expected Result = ["class", "Main", "{"]
}

这将产生以下输出。

else
else
else
else
else
else
else
else
else
[class, Main, {]

相关问题