Problem using Strings after loadTable

edited November 2017 in Questions about Code

I'm confused. Obviously I am missing something basic. If I put data in a table, I can use it normally, but if I save it to a file, then read it back it is not behaving the way I expect.

when my sketch has:

if (New_Table.getString(1, "P_String") == "Row2")

in the original Table it evaluates correctly, but if I save the Table and load it, then it always evaluates as false.

Here is a simplified bit of code demonstrating what I am getting.

Table New_Table;
Table Loaded_Table;

New_Table = new Table();
Loaded_Table = new Table();

New_Table.addColumn("P_String");
New_Table.addColumn("P_Int");
New_Table.addColumn("P_Float");

New_Table.setString(0, "P_String", "Row1");
New_Table.setInt(0, "P_Int", 0);
New_Table.setFloat(0, "P_Float", 0.177);

New_Table.addRow();
New_Table.setString(1, "P_String", "Row2");
New_Table.setInt(1, "P_Int", 42);
New_Table.setFloat(1, "P_Float", 3.14);

saveTable(New_Table, "New_Table.csv", "csv");

Loaded_Table = loadTable("New_Table.csv", "header");

if (Loaded_Table.getInt(1, "P_Int") == 42) println("It behaves as I expect with Int");
else println("Int doesn't work either");

if (Loaded_Table.getFloat(1, "P_Float") == 3.14) println("And with Float");
else println("Flaot doesn't work either");
println();

print("The original String is " + New_Table.getString(1, "P_String"));
if (New_Table.getString(1, "P_String") == "Row2") println(" ... which is equal to Row2 in the original table");
else println("What is wrong here?");
println();

println("The Loaded String is " + Loaded_Table.getString(1, "P_String") + " which should be equal to Row2");
if (Loaded_Table.getString(1, "P_String") == "Row2") println("Ok it works as I expect");
else println("What is wrong here?");

The results are:

It behaves as I expect with Int
And with Float

The original String is Row2 ... which is equal to Row2 in the original table

The Loaded String is Row2 which should be equal to Row2
What is wrong here?

Answers

  • _vk_vk
    edited September 2014 Answer ✓

    Strings should't be compared using == use equals() instead. That might be the issue. Also check String reference.

    hth

  • edited September 2014

    Yes. Never use == to compare strings, unless you really know what you do...
    It is explained both in the String reference and in the == reference...

  • edited September 2014 Answer ✓
    • In Java, the equality operator == compares values stored in variables (and expression operands too).
    • String is a non-primitive, object type and is stored as a memory address value called reference or pointer.
    • Each object has its own memory address. Thus using == for diff. objects will always result false.
    • However, Java's compiler collects all String unique "" literals and re-use them.
    • So it may happen for the == operator result in true for such literal constants.
    • But using that is both risky and frowned upon. But w/ diligent care it's possible!
    • The only safe procedure is always use equals() method for String content comparison!

    In your case above == will always return false b/c some of those String objects are instantiated inside the Table class rather than coming from "" literals!
    Hence they are different objects w/ their own memory addresses, even though their content can be the same!

    Take a look in this example below and see how it works. But just for curiosity. Always go w/ equals(), OK? <):)

    // forum.processing.org/two/discussion/7073/
    // problem-using-strings-after-loadtable
    
    final String MODE2D = "processing.core" + '.' + "PGraphicsJava2D";
    println(MODE2D == JAVA2D);       // true
    println(OPENGL == P3D);          // true for P2+, but false for P1!
    
    final String Graph2D = new String(MODE2D);
    println(Graph2D == JAVA2D);      // false
    println(Graph2D.equals(JAVA2D)); // true
    
    exit();
    

    An even simpler example: :D

    // forum.processing.org/two/discussion/7073/
    // problem-using-strings-after-loadtable
    
    final int NUM_FRUITS = 3;
    final String[] fruits = new String[NUM_FRUITS];
    
    fruits[0] = "açaí";                    // literal  String
    fruits[1] = new String("açaí");        // instance String
    fruits[2] = "açaí";                    // literal  String
    
    println(fruits[0] == fruits[1]);       // false
    println(fruits[0].equals(fruits[1]));  // true
    println(fruits[0] == fruits[2]);       // true
    
    exit();
    

    Even though they've got the same "açaí" content, fruits[1] was forcefully created via a new String.
    However, since fruits[0] & fruits[2] are assigned the same String literal, Java's compiler creates only 1 "açaí",
    and for any repeated occurrence of it, it re-uses that same literal object rather than creating another 1!

  • Thanks guys. Obviously, I am new to Processing / java. Thanks for a great explanation / example GoToLoop!

Sign In or Register to comment.