Java Java Tree Map always gets initialised but shouldn't, why is that?

  • Thread starter Thread starter DottZakapa
  • Start date Start date
  • Tags Tags
    Java Map Tree
Click For Summary
The discussion centers on a Java code issue where a TreeMap is reinitialized during each iteration of a loop, causing it to lose previously stored entries. The problem arises because a new instance of the Skill class is created for each skill name in the loop, which results in a fresh map for each instance. A suggested solution involves checking if the skill already exists in a separate collection, allowing the existing skill to be reused instead of creating a new one. This approach resolves the scope issue and maintains the integrity of the data structure. Proper management of object instances is crucial for retaining values across multiple calls in Java.
DottZakapa
Messages
239
Reaction score
17
TL;DR
The TreeMap in a class, every time the class is accessed the tree map content gets deleted
here is the portion of code

[Code tags added by the Mentors]
Java:
public void addPosition(String name, String skillNames) throws ApplicationException {
    Position ps=new Position (name);   //creating object position
    if(listaPosizioni.get(name)==null) {   //checking if position already present in the list
           listaPosizioni.put(name, ps);   //adding position to the list
     } else throw new ApplicationException();
    for (String s :  skillNames) {
          if (elencoSkills.get(s)==null) {
                  throw new ApplicationException();
          }
          Skill skil= new Skill(s);    // At first cycle of the for  data is inserted properly , at second cycle the TreeMap in the corresponding classes are reset
          ps.addSkill(skil);
          skil.addPosition(ps);
    }
...

class Position{
    private String name;

    private List<Skill> listSkills=new ArrayList<>(); //This list every time is accessed during the for cycle gets initialised again

    public Position(String name) {
        this.name=name;
    }

    public void addSkill(Skill skill) { //method to add skill required for the position
        listSkills.add(skill);
    }

public class Skill {
    private String name;
    private Map<String, Position> positions = new TreeMap<>();
    //private List<Capability> capabilities = new ArrayList<>();
    Skill(String name) {this.name = name;}

    public String getName() {
        return name;
        }

    public List<Position> getPositions() {
        return new ArrayList<>(positions.values());}

    void addPosition(Position position) {
       positions.put(position.getName(), position);
        }
 
Last edited by a moderator:
Technology news on Phys.org
You question (and code) is a bit hazy to me, but it sounds like you are puzzled that the map inside the skil variable is empty after line 10 for all loop iterations? If so, then that follows directly from the map being a member field of the Skill class of which you allocate a new instance on every iteration of the loop.

(My Java is a bit rusty, but you seem to loop over the characters of the skillNames string. Perhaps you meant that parameter type to be some kind of a collection or a whitespace-separated list?)
 
[CODE lang="java" highlight=""15-17,25,""]public void addPosition(String name, String... skillNames) throws ApplicationException {



if(listaPosizioni.get(name)!=null)
throw new ApplicationException(); //checking if position already present in the list
Position ps=new Position (name);
listaPosizioni.put(name, ps); //adding position to the list

for (String s:skillNames) {

if (elencoSkills.get(s)==null) {
throw new ApplicationException();
}
Skill skil= new Skill(s);
ps.addSkill(skil);
skil.addPosition(ps);
}

...//following the class skill

public class Skill {

private String name;
private Map<String, Position> positions = new TreeMap<>();
//private List<Capability> capabilities = new ArrayList<>();

Skill(String name) {this.name = name;}

public String getName() {
return name;
}
public List<Position> getPositions() {
return new ArrayList<>(positions.values());}


void addPosition(Position position) {
positions.put(position.getName(), position);
}
//void addCapability(Capability c) {capabilities.add(c);}
//List<Capability> getCapabilities() {return capabilities;}

public String toString() {
return this.name;
}
}

...//here is the class position

public class Position {

private String name;

private List<Skill> listSkills=new ArrayList<>();

public Position(String name) {
this.name=name;
}

public void addSkill(Skill skill) { //method to add skill required for the position

listSkills.add(skill);

}


public String getName() {
return this.name;
}

public List<String> getApplicants() {
return null;
}

public String getWinner() {
return null;
}

public String toString() {
return this.name;
}
}[/CODE]

now i understood how to insert code in here... should look more clear

So in the for loop it should loop an array of skillNames because the argument is vararg. the thing i don't understand is why when the cycle goes in the class skill, the Map is always reinitialised, doesn't keep the prevues entry.

If i use the following code in the method addPosition all works fine :
Java:
if (listaPosizioni.containsKey(name)) throw new ApplicationException();
        Position position = new Position(name);
        listaPosizioni.put(name, position);
        for (String skillName: skillNames) {
            Skill skill = elencoSkills.get(skillName);
            if (skill == null) throw new ApplicationException();
            position.addSkill(skill);
            skill.addPosition(position);
        }

what the previous doesn't work properly and this does?
 
Last edited:
You have a "scope" problem.
When you do this:
Skill skil; /* creates a name locally in this procedure */
When you do this:

skil = (something); /* aims the variable "skil" at some object or value */
If you want "skil" to retain its value over multiple calls to the procedure, you must declare it OUTSIDE the procedure.
Alternatively, you can start with a new version of "skil" eash time and set its value appropriately using some kind of method (I think you used get(skillName)).

NOTE: Last night when I was trying to edit this, my browser went crazy and I got interrupted; Firefox had updated itself. It seems to have its brains back now. But, I can't remember if I was going to say anything else or not. Sigh.
 
Last edited:
  • Like
Likes jim mcnamara
harborsparrow said:
If you want "skil" to retain its value over multiple calls to the procedure, you must declare it OUTSIDE the procedure.

Or the skill and other references created in a local scope can be stored in a data structure (or in general an object graph) referenced by a variable in an outer scope. For instance, I suppose from the code snippets shown that the skill object is supposed to be linked into the position data which again is linked into the listaPosizioni map.

Edit: spelling
 
Last edited:
  • Like
Likes harborsparrow
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 0 ·
Replies
0
Views
627
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 9 ·
Replies
9
Views
3K
  • · Replies 1 ·
Replies
1
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 28 ·
Replies
28
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 1 ·
Replies
1
Views
1K