【问题标题】:Why can't I access TreeMap declared in a class from another with get method为什么我不能使用 get 方法访问另一个类中声明的 TreeMap
【发布时间】:2019-12-22 20:57:07
【问题描述】:

我正在做一个关于打算在医院使用的计算机系统的 uni 项目。

我有一个“病人”类,其中有一些参数,如心跳、血压(2 个值)和温度,与它相关联,这些参数存储在 TreeMap“参数”中:每个参数都与它的时间一起存储被测量。它们使用“Patient”的 updateParameters() 方法进行更新。

在 updateParameters() 中,我尝试使用 printParameters() 方法检查它们是否存储正确。

然后我有一个“ViewParameters”类,它需要访问患者的参数,但问题是它无法访问这些参数。

我尝试打印患者,它正是选择的患者,所以当我使用该患者的 getParameters() 或 printParameters() 方法时,我使用了正确的方法。

但是:

(我在“ViewParameters”的代码中插入了一些cmets和这个列表的编号)

  1. 当我执行 patient.printParameters() 时,它什么也不打印,只打印初始行(“患者参数:\n”)。

  2. 当我尝试直接从 patient.getParameters() 打印时,它什么也没打印。

  3. 如果我在使用 getParameters() 方法后打印“ViewParameters”类中的参数,它什么也不打印,只打印初始行(“viewParameters 中的参数\n”)。

  4. 即使我直接使用 parametres = Patient.getParameters() 访问参数然后尝试打印它们,它什么也不会打印,只打印初始行(“viewParameters 中的参数”)。

    李>
  5. 我尝试将参数放在“Patient”中公开并执行参数(在“ViewParameters”中)=parameters(在“Patient”中),但它什么也没做。

“病人”类:

public class Patient implements Comparable<Object> {

private String code;
public Map<LocalTime, Integer[]> parameters = new TreeMap<>();


public Map<LocalTime, Integer[]> getParameters() {

    return parameters;
}

public void printParameters() {
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");

    String patient = "patient parameters\n";
    for(LocalTime time: parameters.keySet()) {
        patient += time.format(dtf)  + " ";
        for(Integer parameter: parameters.get(time)) 
            if(parameter == null)
                patient += "- ";
            else
                patient += parameter + " ";
    }
    System.out.println(patient);


}


public void updateParameters(Map<LocalTime, Integer[]> parameters) {

    for(LocalTime time: parameters.keySet()) {
        Integer[] parametersInteger = new Integer[4];
        int i = 0;
        for(Integer parameter: parameters.get(time)) {
            parametersInteger[i] = parameter;
            i++;
        }
        this.parameters.put(time, parametersInteger);

    }

    printParameters();


}

“视图参数”类:

public class ViewParameters extends AbstractTableModel {

String[] column = new String[5];  
Map<LocalTime, Integer[]> parameters = new TreeMap<>();
private Patient patient;

public ViewParameters(String[] tags, Patient patient) {
    int i = 0;
    for(String tag: tags) {
        column[i] = tag;
        i++;
    }
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH.mm");

    this.patient=patient;
    System.out.println("patient in ViewParameters:" + patient);



    patient.printParameters(); //1)


             //2)
    for(LocalTime time: patient.getParameters().keySet()) {
        System.out.println("time: " + time);
        Integer[] parametersInteger = new Integer[4];
        int j = 0;
        for(Integer parameter: patient.getParameters().get(time)) {
            System.out.println("parametro " + j + ": " + parameter);
            parametersInteger[j] = parameter;
            j++;
        }
        parameters.put(time, parametersInteger);
    }


            //3)
    String print = "parameters in viewParameters\n";
    for(LocalTime time1: parameters.keySet()) {
        print += time1 + " ";
        for(Integer parameter: parameters.get(time1)) 
            if(parameter == null)
                print += "- ";
            else
                print += parameters + " ";
    }
    System.out.println(print);


            //4)
    parameters = patient.getParameters(); 


    String print1 = "parameters in viewParameters";
    for(LocalTime time: parameters.keySet()) {
        print1 += time + " ";
        for(Integer parameter: parameters.get(time)) 
            if(parameter == null)
                print1 += "- ";
            else
                print1 += parameter + " ";
    }
    System.out.println(print1);

}

问题似乎在于在它自己的类之外使用 Patient 的方法,因为如果我在“Patient”中使用它,printParameters() 有效,如果我在“ViewParameters”甚至 getParameters() 中使用它则不起作用方法在“ViewParameters”中不起作用。

【问题讨论】:

  • 调试它,看看会发生什么,我的第一个预感:那里根本没有要打印的参数。调试:每隔一行添加一次日志记录或使用断点。
  • @FrankHopkins 我在updateParameters() 方法之后使用了带有断点的调试器,该方法将新值放入TreeMap 并正确存储值。即使我在Patient 中使用了printParameters(),它仍然有效,表明parameters 中有一些东西要打印。我不明白为什么它在Patient之外不起作用

标签: java swing class scope treemap


【解决方案1】:

这是一个关于如何从 Patient 外部调用 Patient 的 printParameters() 方法的工作示例。您在 ViewParameters 中传递给构造函数的 Patient 可能有一个空参数映射。您可以使用 isEmpty() 方法查看地图。

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.TreeMap;

public class Patient implements Comparable<Patient>
{
    private Map<LocalTime, Integer[]> parameters = new TreeMap<>();

    public Map<LocalTime, Integer[]> getParameters()
    {
        return parameters;
    }

    public void printParameters()
    {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");

        StringBuilder patientParameters = new StringBuilder();
        patientParameters.append("patient parameters\n");

        for (LocalTime time : parameters.keySet()) 
        {
            patientParameters.append(time.format(dtf) + " ");
            for (Integer parameter : parameters.get(time))
            {
                if (parameter == null)
                {
                    patientParameters.append("- ");
                }
                else
                {
                    patientParameters.append(parameter + " ");
                }
            }
            patientParameters.append("\n");
        }
        patientParameters.append("============END==========\n");
        System.out.println(patientParameters);
    }

    public void updateParameters(Map<LocalTime, Integer[]> parameters)
    {
        this.parameters.putAll(parameters);
    }

    @Override
    public int compareTo(Patient otherPatient)
    {
        // TODO Auto-generated method stub
        return 0;
    }
}

import java.time.LocalTime;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;

public class Main
{
    private static Random generator = new Random();
    public static void main(String[] args)
    {
        Patient patient = new Patient();
        System.out.println("contains no parameters? " + patient.getParameters().isEmpty());
        patient.printParameters();
        patient.updateParameters(messureNewParameters());
        System.out.println("contains no parameters? " + patient.getParameters().isEmpty());
        patient.printParameters();
        try 
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {

        }
        patient.updateParameters(messureNewParameters());
        patient.printParameters();
    }

    private static Map<LocalTime, Integer[]> messureNewParameters()
    {
        Map<LocalTime, Integer[]> parameters = new TreeMap<>();
        Integer[] values = new Integer[4];
        for (int i = 0; i < values.length; i++)
        {
            values[i] = getNewValue();
        }
        parameters.put(LocalTime.now(), values);
        return parameters;
    }

    private static Integer getNewValue()
    {
        Integer result = generator.nextInt(120);
        if(result < 50)
        {
            return null;
        }
        return result;
    }
}

【讨论】:

    【解决方案2】:

    以下是一些建议:

    我将创建一个 Observation 类,它将名称和值以及最重要的是,将单位封装到一个不可变对象中。见Martin Fowler "Analysis Patterns"

    每个患者都应该有一个私有数据结构。添加便捷方法以允许您向患者添加观察结果。

    Chart 课程会有帮助吗?也许它会封装有用的东西。 Patient 可以有 Chart 这样。它很好地反映了我对医院的理解。

    没有单独的 ViewParameters 类来显示观察结果。将该方法放在PatientChart 中。没有printParameters 方法;写一个正确的toString 覆盖。

    不要这么快就访问私人数据。

    首选不可变数据。

    我可以这样写:

    观察:

    import java.time.LocalDateTime;
    
    public class Observation {
    
        private final LocalDateTime dateTime;
        private final String name;
        private final String value;
        private final String units;
    
        public Observation(String name, String value, String units) {
            if ((name == null) || (name.trim().length() == 0) ) throw new IllegalArgumentException("observation name cannot be blank or null");
            if (value == null) throw new IllegalArgumentException("value cannot be null");
            this.dateTime = LocalDateTime.now();
            this.name = name;
            this.value = value;
            this.units = (units != null) ? units.trim() : "";
        }
    
        public LocalDateTime getDateTime() {
            return dateTime;
        }
    
        public String getName() {
            return name;
        }
    
        public String getValue() {
            return value;
        }
    
        public String getUnits() {
            return units;
        }
    
        @Override
        public String toString() {
            final StringBuffer sb = new StringBuffer("Observation{");
            sb.append("dateTime=").append(dateTime);
            sb.append(", name='").append(name).append('\'');
            sb.append(", value='").append(value).append('\'');
            sb.append(", units='").append(units).append('\'');
            sb.append('}');
            return sb.toString();
        }
    }
    

    患者:

    import java.util.ArrayList;
    import java.util.List;
    
    public class Patient {
    
        private String name;
        private List<Observation> chart;
    
        public Patient(String name) {
            if ((name == null) || (name.trim().length() == 0)) throw new IllegalArgumentException("name cannot be blank or null");
            this.name = name;
            this.chart = new ArrayList<>();
        }
    
        public String getName() {
            return name;
        }
    
        public void addObservation(Observation observation) {
            if (observation != null)  {
                this.chart.add(observation);
            }
        }
    
        @Override
        public String toString() {
            final StringBuffer sb = new StringBuffer("Patient{");
            sb.append("name='").append(name).append('\'');
            sb.append(", chart=").append(chart);
            sb.append('}');
            return sb.toString();
        }
    }
    

    【讨论】:

    • 非常感谢您的时间和回答。 1)观察类似乎只是一个改进,如果我错了,请纠正我,这是我第一次使用java,但我仍然无法理解为什么Patient的方法在类之外不起作用,我感觉 Observation 类不是对此的“直接解决方案”。 2) 我将 ViewParameters 用作显示参数的 JTable 的 AbstractTableModel,这就是为什么它是一个单独的类。 3)我不能真正使用 JSON,因为我只需要使用 Java 和 Java Swing,实际上我什至不知道 JSON 是什么。
    • 你是学生;我认为所有的教育都是值得的。您应该了解 JSON 是什么。我对直接解决方案的兴趣不如我对指导您考虑更好的方法的兴趣。将另一个类的数据的视图和更新分开是错误的。面向对象编程将状态和行为封装在一起。您应该将状态的访问和操作保留在一个类中。
    猜你喜欢
    • 1970-01-01
    • 2019-11-17
    • 2014-03-28
    • 1970-01-01
    • 2011-01-09
    • 2012-08-03
    • 2015-02-07
    • 1970-01-01
    • 2018-07-31
    相关资源
    最近更新 更多