从文件导入时,TreeSet 仅复制第一项

TreeSet duplicates just the first item when importing from file

我实现了一个名为 EventSet 的 class,它包含一个带有自定义比较器的 TreeSet。 comparator 应该与 equals 一致,因为在将元素添加到集合之前,TreeSet 似乎使用 compare 或 compareTo 进行所有需要的比较。我的应用程序需要读取包含一系列命令的文本文件,一个可能的命令是导入指定事件的文本文件。因此,一个假设的 event.txt 文件包含几行,例如 "IN LOGIN 18082019 ab001 45.457, 9,181 A",应用程序调用一个方法来解析字符串并将其转换为一个事件对象,该对象被添加到 EventSet 实例中。这里的问题很奇怪:一切正常,除非在命令文件中我尝试导入相同的 event.txt 文件两次,文件的第一行被转换为事件并作为重复项插入集合中,即使等于和比较说它是重复的。无论我如何更改它,这只会发生在文件的第一行。到目前为止,这是我的一些代码:

Class 事件集:

private static EventSet instance;
private TreeSet<Event> eventTree;

//costruttore
private EventSet() {
    EventComparator comp = new EventComparator();
    this.eventTree = new TreeSet<Event>(comp);
}

public static EventSet getInstance() {
    if (instance == null) {
        instance = new EventSet();
    }
    return instance;
}

public TreeSet<Event> getEventTree() {
    return eventTree;
}

public void setEventTree(TreeSet<Event> eventTree) {
    this.eventTree = eventTree;
}


public boolean add(Event e) {
    return this.eventTree.add(e);
}

public boolean add(Set<Event> set) {
    return this.eventTree.addAll(set);
}

Class 事件比较器:

public EventComparator() {
    super();
}

@Override
public int compare(Event e1, Event e2) {
    if(e1.equals(e2)) {
        return 0;
    } else if(e1.getTimestamp().compareTo(e2.getTimestamp())>=0) {
        return 1;
    } else {
        return -1;
    }
}

Class 事件:

RegState reg_state;
String user_id;
LogState log_state;
Position position;
Date timestamp;
Emotion emotion;

//costruttore
public Event(RegState reg_state, LogState log_state, Date timestamp, String user_id, Position pos, Emotion emo) {
    this.reg_state = reg_state;
    this.user_id = user_id;
    this.log_state = log_state;
    this.position = pos;
    this.timestamp = timestamp;
    this.emotion = emo;
}



public RegState getReg_state() {
    return reg_state;
}



public void setReg_state(RegState reg_state) {
    this.reg_state = reg_state;
}



public String getUser_id() {
    return user_id;
}


public void setUser_id(String user_id) {
    this.user_id = user_id;
}


public LogState getLog_state() {
    return log_state;
}


public void setLog_state(LogState log_state) {
    this.log_state = log_state;
}


public Position getPosition() {
    return position;
}

public void setPosition(Position position) {
    this.position = position;
}

public Date getTimestamp() {
    return timestamp;
}

public void setTimestamp(Date timestamp) {
    this.timestamp = timestamp;
}

public Emotion getEmotion() {
    return emotion;
}

public void setEmotion(Emotion emotion) {
    this.emotion = emotion;
}


@Override
public String toString() {
    String s = reg_state.toString()+" | "+log_state.toString()+" | "+InputLine.d_format.format(timestamp)+" | "+user_id+" | "+position.toString()+" | "+emotion.toString();
    return s;
}


@Override
public int hashCode() {
    return Objects.hash(user_id, reg_state, log_state, position, timestamp, emotion);
}


@Override
public boolean equals(Object obj) {
    if (obj==null) {
        return false;
    }
    if (this == obj) {
        return true;
    }
    if (obj instanceof Event) {
        Event e = (Event)obj;
        if (this.user_id.equals(e.getUser_id()) & this.log_state==e.getLog_state() & 
                this.position.equals(e.getPosition()) & this.timestamp.equals(e.getTimestamp()) & this.emotion==e.getEmotion() & this.reg_state==e.getReg_state()) {
            return true;
        }
    }
    return false;
}

导入cmd.txt文件的方法:

    void import_cmd() throws NumberFormatException, ParseException {
    FileReader fr;
    BufferedReader br;
    String current;

    try {
        fr = new FileReader(cmd_path);
        br = new BufferedReader(fr);
    } catch (FileNotFoundException e) {
        if (this.controller != null) {
            controller.get_message("Error: file not found at this location "+cmd_path.getAbsolutePath());
        }
        return;
    }

    InputLine line;

    try {
        current = br.readLine();
        while (current != null) {
            if (this.controller != null) {
                line = new InputLine(current, controller);
            } else {
                line = new InputLine(current);
            }
            if (line.cmd_check() == 1) {
                String extracted = line.getIn_line().substring(line.getIn_line().indexOf("(")+1, line.getIn_line().indexOf(")"));
                String path = this.event_path.getAbsolutePath()+File.separator+extracted;

                try {
                    import_events(path);
                    if (this.controller != null) {
                        controller.get_message("File "+ extracted + " successfully imported ");
                    }
                } catch (FileNotFoundException e) {
                    if (this.controller != null) {
                        controller.get_message("Error: file not found at "+path);
                    }
                } catch (IOException ioe) {
                    if (this.controller != null) {
                        controller.get_message("Error: unable to read from file at "+path);
                    }
                }
            } else if (line.cmd_check() == 2) {
                boolean valid = line.validate_date_iterval(line.getIn_line());
                if (valid) {
                    //call create map
                    if (this.controller != null) {
                        controller.get_message("Map correctly created for "+ line.getIn_line());
                    }
                } else if (this.controller != null) {
                    controller.get_message("Invalid date at "+ line.getIn_line()+": unable to create map");
                }

            }
            current = br.readLine();
        }
        br.close();
        fr.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

导入event.txt个文件的方法:

private void import_events(String path) throws FileNotFoundException, IOException, ParseException {   

    FileReader fr;
    BufferedReader br; 
    String current; 
    String[] tokens;


    fr = new FileReader(path);
    br = new BufferedReader(fr); 
    current = br.readLine(); 

    if (current == null) {
        if (this.controller != null) {
            controller.get_message("Warning: event file is empty, no events to import");
        }
        br.close(); 
        fr.close(); 
        return; 
        }

    InputLine il;
    while (current != null) { 

        current = current.trim(); 

        if (this.controller != null) {
            il = new InputLine(current, controller);
        } else {
            il = new InputLine(current);
        }

        if (il.line_ok()) { 
            tokens = current.split(Pattern.quote(" "));

            RegState reg_state = RegState.valueOf(tokens[0]); 

            String user_id = tokens[3]; 

            LogState log_state = LogState.valueOf(tokens[1]);


            InputLine.d_format.setLenient(false); 
            Date timestamp = InputLine.d_format.parse(tokens[2]);


              String[] latlong = tokens[4].split(","); 
              double lat = Double.parseDouble(latlong[0]); 
              double longi = Double.parseDouble(latlong[1]); 
              Position pos = Position.create(lat, longi);

              if (pos == null) { 
                  if (this.controller != null) {
                      controller.get_message("Error: invalid coordinates at "+current+", event ignored");
                  }
                  break; 
              }

              Emotion emotion = Emotion.valueOf(tokens[5]);

              Event event = new Event(reg_state,log_state, timestamp, user_id, pos, emotion);

              boolean added=EventSet.getInstance().add(event); 
              if (this.controller != null) {
                  if (added) {
                      controller.get_message("Event successfully created with "+ current);
                  } else if (!added) {
                      controller.get_message("Duplicated event was ignored at "+ current + ": event already present in the set");
                  }
              }
            }
            current = br.readLine();
        }
        br.close(); 
        fr.close(); 
        return; 
        }

我用于测试的文本文件- cmd.txt

import(eventi1.txt)
import(eventi2.txt)
create_map(10062019-12062019)
import(eventi2.txt)

eventi2.txt

IN LOGIN 10062019 ab00x 45.464,9.191 A
IN LOGIN 10062019 ab002 45.463,9.192 F
IN LOGOUT 10062019 ab001 45.458,9.181 S
OUT LOGOUT 11062019 ab002 45.473,9.173 N
IN LOGIN 11062019 ac003 45.461,9.187 T
IN LOGIN 12062019 ad004 45.464,9.188 T
OUT LOGOUT 12062019 ab001 45.473,9.173 N

部分结果图片:

已解决: 显然,这个问题是由调用一个方法引起的,该方法读取文件并在另一个从文件读取的方法中对树执行 add() 。我编辑了 import_events() 和 import_cmd() 方法,现在一切正常。

private HashSet<Event> import_events(String path) throws FileNotFoundException, IOException, ParseException {     

    FileReader fr1;
    BufferedReader br1; 
    String current; 
    String[] tokens;
    HashSet<Event> set = new HashSet<Event>();

    fr1 = new FileReader(path);
    br1 = new BufferedReader(fr1); 
    current = br1.readLine(); 

    if (current == null) {
        if (this.controller != null) {
            controller.get_message("Warning: event file is empty, no events to import");
        }
        br1.close(); 
        fr1.close(); 
        return set; 
        }

    InputLine il;
    while (current != null) { 

        current = current.trim(); 

        if (this.controller != null) {
            il = new InputLine(current, controller);
        } else {
            il = new InputLine(current);
        }

        if (il.line_ok()) { 

            tokens = current.split(Pattern.quote(" "));

            RegState reg_state = RegState.valueOf(tokens[0]); 

            String user_id = tokens[3]; 

            LogState log_state = LogState.valueOf(tokens[1]);



            InputLine.d_format.setLenient(false); 
            Date timestamp = InputLine.d_format.parse(tokens[2]);


              String[] latlong = tokens[4].split(","); 
              double lat = Double.parseDouble(latlong[0]); 
              double longi = Double.parseDouble(latlong[1]); 
              Position pos = Position.create(lat, longi);

              if (pos == null) { 
                  if (this.controller != null) {
                      controller.get_message("Error: invalid coordinates at "+current+", event ignored");
                  }
                  break; 
              }

              Emotion emotion = Emotion.valueOf(tokens[5]);

              Event event = new Event(reg_state,log_state, timestamp, user_id, pos, emotion);

              set.add(event);
            }
            current = br1.readLine();
        }
        br1.close(); 
        fr1.close(); 
        return set; 
        }

现在 import_events() returns 文件中包含事件的 HashSet。

import_cmd() 使用 HashSet 作为在树上调用 addAll() 的参数。

void import_cmd() throws NumberFormatException, ParseException {
    FileReader fr;
    BufferedReader br;
    String current;

    try {
        fr = new FileReader(cmd_path);
        br = new BufferedReader(fr);
    } catch (FileNotFoundException e) {
        if (this.controller != null) {
            controller.get_message("Error: file not found at this location "+cmd_path.getAbsolutePath());
        }
        return;
    }

    InputLine line;
    Set<Event> toAdd=new HashSet<Event>();

    try {
        current = br.readLine();
        while (current != null) {
            if (this.controller != null) {
                line = new InputLine(current, controller);
            } else {
                line = new InputLine(current);
            }
            if (line.cmd_check() == 1) {
                String extracted = line.getIn_line().substring(line.getIn_line().indexOf("(")+1, line.getIn_line().indexOf(")"));
                String path = this.event_path.getAbsolutePath()+File.separator+extracted;

                try {
                    toAdd=import_events(path);
                    if (this.controller != null) {
                        controller.get_message("File "+ extracted + " successfully imported ");
                    }
                } catch (FileNotFoundException e) {
                    if (this.controller != null) {
                        controller.get_message("Error: file not found at "+path);
                    }
                } catch (IOException ioe) {
                    if (this.controller != null) {
                        controller.get_message("Error: unable to read from file at "+path);
                    }
                }
                boolean addOk=EventSet.getInstance().add(toAdd);
                if (this.controller!=null) {
                    if (addOk) {
                        controller.get_message("Events added");
                    } else {
                        controller.get_message("No events to add");
                    }
                }
            } else if (line.cmd_check() == 2) {
                boolean valid = line.validate_date_iterval(line.getIn_line());
                if (valid) {
                    Date[] dates = line.convertIntervaltoDates(line.intervalExtract(line.getIn_line()));
                    createmap(dates[0], dates[1]);
                    if (this.controller != null) {
                        controller.get_message("Map correctly created for "+ line.getIn_line());
                    }
                } else if (this.controller != null) {
                    controller.get_message("Invalid date at "+ line.getIn_line()+": unable to create map");
                }

            }
            current = br.readLine();
        }
        br.close();
        fr.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}