HashMap float by reference, not by value?

Everything I find online, stackoverflow, says a HashMap<String, Float>(); should store only references to the floats.

When I store something in the hashmap, use hashmap.get() to get the float object, I can't seem to write to the original object. In this example I try to get and modify the original float1 variable without success. It seems to modify a new float stored in the hashmap in test2, test1 does nothing.

Float float1 = 1.1;
HashMap<String, Float> hm = new HashMap<String, Float>();

void setup() {
  hm.put("float1", float1);

  Float f1 = hm.get("float1");
  f1 = 5.5;

  println("test1");
  println("float1: " + float1);
  println("hashMap float1: " + hm.get("float1"));
  println("both should  should be " + f1);
  println();

  println("test2");
  hm.put("float1", f1);
  println("float1: " + float1);
  println("hashMap float1: " + hm.get("float1"));
  println("both should  should be " + f1);
  println();
}

Here's the output

test1
float1: 1.1
hashMap float1: 1.1
both should  should be 5.5

test2
float1: 1.1
hashMap float1: 5.5
both should  should be 5.5

Answers

  • when you put something in the HashMap it holds a copy of the value, not the reference to the old variable.

    stackoverflow, says a HashMap<String, Float>(); should store only references to the floats.

    Technically, it uses a reference to a float variable but a copy of the old value, not the same pointer address as the old variable. Since the value not the reference

    Float float1 = 1.1;
    HashMap<String, Float> hm = new HashMap<String, Float>();
    
    void setup() {
    
    
      println (float1); 
      hm.put("float1", float1);
    
    
      Float f1 = hm.get("float1");
    
      f1 = 10.0; 
      println (f1);
    
      f1 = hm.get("float1");
      println(f1);
    }
    
  • edited April 2018

    So is there a way it could be done?

    I have a game style ` console window, and I want to be able to set and retrieve variables by typing in their names. I thought I could just add all the variables I wanted to make accessible to a hashmap. There has to be a better way than hard coding responses for every variable.

    It wouldn't be terrible to do it with a switch(), but I'd like to retain tweak-mode functionality and it seems using switch breaks that.

  • Answer ✓

    I want to be able to set and retrieve variables by typing in their names

    Do you want to do that for debugging?

    Did you look at the debugger / processing? In theory it does exactly that.

    There has to be a better way than hard coding responses for every variable.

    variables should be in an array, then you can easily show them

    show your code so let's explain what you mean

    Example:

    ArrayList<Ball> balls;
    boolean showData=false; 
    
    void setup() {
    
      size(400, 800);
      balls = new ArrayList();
    
      // for-loop
      for (int i = 0; i < 10; i++) { 
    
        int rectWidth = 20;
        int rectHeight = 20;
        float rCol, gCol, bCol;
    
        rCol = random(255);
        gCol = random(255);
        bCol = random(255);
    
        color newColor = color(rCol, gCol, bCol);
    
        Ball newBall = new Ball(random(width-rectWidth), random(height-rectHeight), 
          rectWidth, rectHeight, 
          newColor); 
    
        balls.add(newBall);
        //
      } // for
      //
    } // func 
    
    void draw() {
    
      background(255); // white
    
      if (showData) {
        for (int i = 0; i < balls.size(); i++) { 
          Ball ball = balls.get(i);
          ball.displayData(i*13 + 40);
        } // for
      } else {
    
        // for-loop
        for (int i = 0; i < balls.size(); i++) { 
          Ball ball = balls.get(i);
          ball.display( false );
        } // for
    
        // for-loop backward to remove balls 
        for (int i = balls.size()-1; i>=0; i--) { 
          Ball ball = balls.get(i);
          if (!ball.isAlive) // ! means not 
            balls.remove( i );  // remove i from list
        } // for
    
        fill(0);  // black 
        text ("number of balls: "
          +balls.size()
          +". \nPress a key.", 
          14, 14);
        //
      }
      //
    } // func 
    
    void keyPressed() {
      showData= !showData;
    }
    
    // ==================================================
    
    class Ball {  
    
      // position
      float x;
      float y;
    
      // size
      float w;
      float h;
    
      // color 
      color colBall;
    
      // Is it still alive?
      boolean isAlive = true; 
    
      // constr 
      Ball(float tempX, float tempY, 
        float tempW, float tempH, 
        color tempColBall) {
    
        x = tempX;
        y = tempY;
        w = tempW;
        h = tempH;  
        colBall = tempColBall;
      } // constr 
    
      void display( boolean withStroke ) {
    
        if (withStroke) {
          strokeWeight(3); 
          stroke(0);
        } else {
          noStroke();
        }
        fill(colBall);
        rect(x, y, w, h);
    
        y+=3;
    
        if (y > height+12) { 
          // isAlive = false;
          y=0;
        }
      } // method 
    
      void displayData( int yTextValue ) {
        text(x+", "+y, 33, yTextValue);
      }
      //
    } // class
    //
    
  • edited April 2018
    Float f1, f2;
    
    f1 = PI;
    f2 = PI;
    
    println(f1, f2); // 3.1415927 3.1415927
    println(f1 == f2); // false. They're diff. objects.
    println(f1.equals(f2)); // true. B/c their content is the same.
    
    f1 = f2;
    println(f1 == f2); // true. B/c now they point to the same object!
    
    exit();
    
  • 3.1415927 3.1415927
    false
    true
    
  • edited April 2018

    float with a small f

    float f1, f2;
    
    f1 = PI;
    f2 = PI;
    
    println(f1, f2); // 3.1415927 3.1415927
    println(f1 == f2); // false
    //println(f1.equals(f2)); // true
    
    // exit();
    

    Result

    • 3.1415927 3.1415927

    • true

  • edited April 2018

    edited: https://files.fm/u/ajs3c7hf new version has better autocomplete various bugfixes

    Here's my project. It's intended to be a reusable template to help speed up prototyping games.

    The console can view and set variables, but it can also call functions with arguments, which I can't do from debugger. It also has a nice benchmarking tool. I have a bunch of snippets from other old game projects I want to add in as well like a graph logger to show variables changing over time. That's another case I wish I knew the java way around not having pointers, I'd like to be able to add any of those variables accessible from console to the graph display easily.

    I'm looking for better ways to implement the way it references functions and variables, ideally more directly like I'm used to in c++.

    Theres an autocomplete system for the console window, still a bit buggy.

  • impressive but I don't really have an idea for you...

  • @lmccandless Can you share your final solution?

    To answer your question, what you need to do is not to use get but to set. Or you could get a copy of the current position, modify this value, and then set the position with that new value. I guess this is what you implemented at the end?

    Float float1 = 1.1;
    HashMap<String, Float> hm = new HashMap<String, Float>();
    
    void setup() {
      hm.put("float1", float1);
    
      Float f1 = hm.get("float1");
      f1 = 5.5;
      hm.replace("float1",6.6);
    
      println("hashMap float1: " + hm.get("float1"));  //Returns 6.6
    
    }
    

    Kf

  • edited April 2018

    No, he tries to have a list of all his variables to be able to quickly view their values in a console

    He want to use HashMap() for that but this won't work.

    Idea

    if you know the names of the variables you can hard code them

    (js eval is NOT needed here at all):

    // https : // forum.processing.org/two/discussion/comment/121903#Comment_121903
    // https : // forum.processing.org/two/discussion/17161/eval-js-with-power-general-help-on-eval-js-eval
    // 
    float float1 = 1.1;
    float float2 = 233.1;
    float float3 = 247.1;
    
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    
    // for evaluation of math 
    javax.script.ScriptEngine js1; 
    
    String test2="", 
      input="";
    
    void setup() {
      size(611, 311);
      background(133); 
      js1 = new ScriptEngineManager().getEngineByName("js");
    }
    
    void draw() {
      background(133); 
    
      text("Type: view float1, view float2, view float3 and hit return.  ", 24, 24);
      text(input, 24, 44);
      text(test2, 24, 64);
    }
    
    void keyPressed() {
      if (key==ENTER||key==RETURN) {
        input=input.replace("view ", ""); 
        // this gives us : float1 as String
        float value = 0.0; 
        switch (input.trim().toLowerCase()) {
        case "float1":
          value=float1; 
          break; 
        case "float2":
          value=float2; 
          break; 
        case "float3":
          value=float3; 
          break;
        }
        test2 = evalJS(this, js1, str(value));
        input="";
      }
      //---
      else if (key==BACKSPACE) {
        if (input.length()>0)
          input=input.substring(0, input.length()-1);
        test2 = ""; // reset
      }
      //----
      else {
        // normal input
        input+=key;
        // test2 = ""; // reset
      }
    }
    
    String evalJS(PApplet pa, ScriptEngine js, String expression) {
      js.put("p", pa);
    
      try {
        Object obj1=js.eval(expression);
        return obj1.toString();
      }
      catch (ScriptException cause) {
        //throw new RuntimeException(cause);
        println("Error with: "
          +expression 
          + ", cause: "
          +cause); 
        return "";
      }
    } // 
    // 
    
  • edited April 2018

    https://github.com/lmccandless/gameTemplate Here's an update

    My solution was to just use the variables stored in the hashmap. It's not ideal for performance or usability, but not all variables need to be accessible to the console, so I guess it's a manageable system.

Sign In or Register to comment.