在Java中,将布尔值赋给变量时,布尔值的值会发生变化。

huangapple go评论64阅读模式
英文:

Value of Boolean changes when assign to variable - java

问题

I'm doing tokenize the line(String).

I have to tokenize literally this line.

class Main { into [ "class" , "Main", "{" ]

The progress is like there are conditions I variablized like boolean conditionA = (isSpace && isSymbol) .

and In the for loop I inspect a character of the line. In example above, like inspect c and l and a .. so on.

And Here is problem.

I made a boolean variable

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

Character.isWhitespace(currentChar) in currentChar is a space right next to class in class Main {

Because currentChar is now holding a space value, so isWhiteSpace is true.

!tempWord.isEmpty() in tempWord is a class so tempWord holds "class" .

Also, tempWord is now holding "class" so the value is !false . So true .

I expected their value to be true && true . So the variable holds these result also true.

But It didn't work like I expected.

Because I didn't believe my self over computer, So I checked debugger.

在Java中,将布尔值赋给变量时,布尔值的值会发生变化。

And declaration of isTailwhiteSpace .

在Java中,将布尔值赋给变量时,布尔值的值会发生变化。

How can isTailWhiteSpace be false?

I also checked the possible side effects, But the isTailWhiteSpace is only used once and never redeclared.

And for more information, This is usage of above code if statement,

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

Here is reproducible code.

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", "{"]
    }
}
英文:

I'm doing tokenize the line(String).

I have to tokenize literally this line.

class Main { into [ &quot;class&quot; , &quot;Main&quot;, &quot;{&quot; ]

The progress is like there are conditions I variablized like boolean conditionA = (isSpace &amp;&amp; isSymbol) .

and In the for loop I inspect a character of the line. In example above, like inspect c and l and a .. so on.

And Here is problem.

I made a boolean variable

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

Character.isWhitespace(currentChar) in currentChar is a space right next to class in class Main {

Because currentChar is now holding a space value, so isWhiteSpace is true.

!tempWord.isEmpty() in tempWord is a class so tempWord holds &quot;class&quot; .

Also, tempWord is now holding &quot;class&quot; so the value is !false . So true .

I expected their value to be true &amp;&amp; true . So the variable holds these result also true.

But It didn't work like I expected.

Because I didn't believe my self over computer, So I checked debugger.

在Java中,将布尔值赋给变量时,布尔值的值会发生变化。

And declaration of isTailwhiteSpace .

在Java中,将布尔值赋给变量时,布尔值的值会发生变化。

How can isTailWhiteSpace be false?

I also checked the possible side effects, But the isTailWhiteSpace is only used once and never redeclared.

And for more information, This is usage of above code if statement,

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

Here is reproducible code.

import java.util.ArrayList;
import java.util.Arrays;
class BooleanDemo {
private static String tempWord = &quot;&quot;;
private static char currentChar;
private static boolean isTailWhiteSpace = Character.isWhitespace(currentChar) &amp;&amp; !tempWord.isEmpty();
//Just for symbol checking
private static final Character[] symbols = {
&#39;(&#39;, &#39;)&#39;, &#39;{&#39;, &#39;}&#39;, &#39;[&#39;, &#39;]&#39;, &#39;.&#39;, &#39;,&#39;, &#39;;&#39;, &#39;+&#39;, &#39;-&#39;, &#39;*&#39;, &#39;/&#39;, &#39;|&#39;, &#39;&amp;&#39;, &#39;&lt;&#39;, &#39;&gt;&#39;, &#39;=&#39;, &#39;~&#39;
};
private static final ArrayList&lt;Character&gt; symbolList = new ArrayList&lt;&gt;(Arrays.asList(symbols));
private static boolean isSymbol = symbolList.contains(currentChar);
public static ArrayList&lt;String&gt; tokenize(String line){
ArrayList&lt;String&gt; tokenizedLine = new ArrayList&lt;&gt;();
for(char c : line.toCharArray()){
currentChar = c;
if(isTailWhiteSpace){
tokenizedLine.add(tempWord);
tempWord = &quot;&quot;;
}else if(!isSymbol){
tempWord += currentChar;
}else{
System.out.println(&quot;else&quot;);
}
}
return tokenizedLine;
}
public static void main(String[] args){
String sampleLine = &quot;class Main {&quot;;
System.out.println(BooleanDemo.tokenize(sampleLine));
//Expected Result = [&quot;class&quot;, &quot;Main&quot;, &quot;{&quot;]
}
}

答案1

得分: 2

在初始初始化之后,在代码中没有动态刷新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); // 我认为,尽管a的值已经改变,但b仍然为true

每当tempWord发生变化时,你需要重新计算isTailWhiteSpace的值。如果以a和b作为示例,应该像这样:

String a = "";
boolean b = true && a.isEmpty();
System.out.println(b); // b是true
a = "abc";
System.out.println(b); // 我认为,尽管a的值已经改变,但b仍然为true
b = true && a.isEmpty();
System.out.println(b); // 现在,b是false

在你的代码中:

if (isTailWhiteSpace) {
    tokenizedLine.add(tempWord);
    tempWord = "";
    // 这里,tempWord发生了变化,你需要重新计算
} else if (!isSymbol) {
    tempWord += currentChar;
    // 这里,tempWord发生了变化,你需要重新计算
} else {
    System.out.println("else");
}

工作中时间不多,你可以自己处理细节,或者提取一个方法来计算isTailWhiteSpace

英文:

After the initial initialization, you did not dynamically refresh the value of isTailWhiteSpace in the code

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

Can you understand this code:

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

You need to recalculate the value of isTailWhiteSpace whenever tempWord changes. If I give a and b as an example, it should be like this:

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

In you code:

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

Working, don't have much time, you can handle the details yourself, or you can extract a method to calculate isTailWhiteSpace

答案2

得分: 0

您正在寻找的概念是一个过程,而不是一个赋值。

例如,您将变量分配如下:

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

我想象您是假设每次调用_isTailWhiteSpace_ 时,它将运行赋值语句。
换句话说,currentChar 将具有不同的值。

您在这里寻找的是一个过程,Java 中称之为 方法

private static boolean isTailWhiteSpace() {
    return Character.isWhitespace(currentChar) &amp;&amp; !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 字符的列表,您需要在循环中添加一个新的 else-if 条件。

我不确定您在何处需要 println 来输出 "else",所以我将其添加到了追加块中。

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

因此,总体而言,您的代码将如下所示。

private static String tempWord = &quot;&quot;;
private static char currentChar;

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

//Just for symbol checking
private static final Character[] symbols = {
    &#39;(&#39;, &#39;)&#39;, &#39;{&#39;, &#39;}&#39;, &#39;[&#39;, &#39;]&#39;, &#39;.&#39;, &#39;,&#39;, &#39;;&#39;, &#39;+&#39;, &#39;-&#39;, &#39;*&#39;, &#39;/&#39;, &#39;|&#39;, &#39;&amp;&#39;, &#39;&lt;&#39;, &#39;&gt;&#39;, &#39;=&#39;, &#39;~&#39;
};
private static final ArrayList&lt;Character&gt; symbolList = new ArrayList&lt;&gt;(Arrays.asList(symbols));

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

public static ArrayList&lt;String&gt; tokenize(String line){
    ArrayList&lt;String&gt; tokenizedLine = new ArrayList&lt;&gt;();

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

    return tokenizedLine;
}

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

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

这将产生以下输出。

else
else
else
else
else
else
else
else
else
[class, Main, {]
英文:

The concept you are looking for is a procedure, and not an assignment.

For example, you're assigning the variable as follows.

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

I imagine, you are presuming that whenever you call isTailWhiteSpace, that it will run the assignment statement.
In other words, currentChar would be a different value.

What you're looking for here is a procedure, which Java refers to as methods.

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

Furthermore, the conditional statement can be reduced.
If the Character.isWhitespace(currentChar) expression returns true, then !tempWord.isEmpty() will, hence, be true.

The String#isEmpty method is just a quicker way of typing string.length == 0.
In fact, if you review the source-code for isEmpty you'll find that, that is the exact statement it executes.

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

Similarly, your isSymbol statement will not execute its assignment when it is resolved within the code.
You'll have to change this to a method, as well.

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

Since there are now methods, make sure to append the opening and closing parentheses on their usages.

Finally, to derive a list that also contains a symbols character, you'll need a new else-if conditional within your for-loop.

I am not sure where you require the println for "else", so I added it to the appending block.

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

So, altogether, your code would be as follows.

private static String tempWord = &quot;&quot;;
private static char currentChar;

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

//Just for symbol checking
private static final Character[] symbols = {
    &#39;(&#39;, &#39;)&#39;, &#39;{&#39;, &#39;}&#39;, &#39;[&#39;, &#39;]&#39;, &#39;.&#39;, &#39;,&#39;, &#39;;&#39;, &#39;+&#39;, &#39;-&#39;, &#39;*&#39;, &#39;/&#39;, &#39;|&#39;, &#39;&amp;&#39;, &#39;&lt;&#39;, &#39;&gt;&#39;, &#39;=&#39;, &#39;~&#39;
};
private static final ArrayList&lt;Character&gt; symbolList = new ArrayList&lt;&gt;(Arrays.asList(symbols));

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

public static ArrayList&lt;String&gt; tokenize(String line){
    ArrayList&lt;String&gt; tokenizedLine = new ArrayList&lt;&gt;();

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

    return tokenizedLine;
}

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

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

This will yield the following output.

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

huangapple
  • 本文由 发表于 2023年5月29日 13:33:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354879.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定