Damerian
Damerian

Reputation: 17

Inexplicable map behavior

I am trying to build a program for a school assignment that generates transitive closures given a set o Functional Dependencies. I am using JAVA . To make it recognize string subsets i have had to build a Class called Attribute consisting of a char and a boolean field (to help further recognition of strings containing character sequences

Then i have a class called FunctionalDependency which simply has two maps of <Integer, Attribute>. the first map represents the left hand and the second the right hand of an attribute.

Finally my main program that does the actual calculationhas a map of Integer,FunctionalDependency, which represents the set of dependencies that the user wants to input. My problem is located in the method insertFD() and more specifically in the first for{} block. Whilst in the for block the map seems to have the values i want , outside it (meaning after the last call of the loop) it copies to all the positions of the map the last character of the input destroying the further calculations.

   /*The method for inserting a new FD*/
   public void insertFD() throws IOException{
       Map<Integer, Attribute > tempMapLeft= new HashMap<Integer,Attribute>();
       Map<Integer, Attribute > tempMapRight= new HashMap<Integer,Attribute>();
       Attribute tempAttrLeft = new Attribute();
       Attribute tempAttrRight = new Attribute();
       FunctionalDependency tempDependency=new FunctionalDependency();


       String tempString;
       BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in));
       System.out.println("Please give the string for the left hand:");
       System.out.flush();
       tempString=stdin.readLine();
       tempString.toUpperCase();
       System.out.println("Your input is "+tempString);


       for(int j=0;j<tempString.length();j++)
       {
           System.out.println("for j="+j+"letter is "+(tempString.toCharArray()[j]));
           tempAttrLeft.setTheCharacter(tempString.toCharArray()[j]);
           tempAttrLeft.setCheck(true);
           tempMapLeft.put(j, tempAttrLeft);
           System.out.println("I just inserted "+ tempAttrLeft.getTheCharacter());
           System.out.println("Here is the proof: "+tempMapLeft.get(j).getTheCharacter());
       }
       System.out.println(tempMapLeft.get(0).getTheCharacter());
       System.out.println(tempMapLeft.get(1).getTheCharacter());
       tempDependency.setLeftHand(tempMapLeft);
       //fSet.put(number, tempDependency);
       //fSet.get(number).setLeftHand(tempMapLeft);

       System.out.flush();
       System.out.println("Your left hand is at 0 "+  tempDependency.getLeftHand().get(0).getTheCharacter());
       System.out.println("Your left hand is at 1 "+ tempDependency.getLeftHand().get(1).getTheCharacter());

I am not any java expert but i cannot see the mistake in my code, i would be glad if you could help me, thanks in advance.

Upvotes: 0

Views: 86

Answers (3)

user180100
user180100

Reputation:

In your for loop, you are using an Attribute instance which is the same for every j, so after the loop, every map entry contains the same Attribute

Upvotes: 0

Affe
Affe

Reputation: 47974

Your problem is that you keep re-using the same tempAttrLeft and tempAttrRight in each pass of the loop. Every key in the map is pointing to the same object! You need to create a new tempAttrLeft and tempAttrRight on each pass of the loop. The map keeps a reference to the object you put in it, it doesn't "copy" it. So when you change the values on the next pass of the loop, that map key is pointed to the same one with the new values.

Upvotes: 2

Gaurav
Gaurav

Reputation: 1567

I am not sure what is the expected and actual output. But few things you can try :

  1. You will not get the uppercase in tempString.toUpperCase(); This is because of immutability feature of String. Instead do : tempString = tempString.toUpperCase();
  2. Re-initialize the tempString when accepting input for right hand.

Upvotes: 0

Related Questions