Java Hashtable保存到文件中

时间:2014-05-29 12:06:10

标签: java file hashtable

我写了这篇日记,用户可以选择日期,为该日期写一些文字并保存。 文本存储在每个日期的哈希表中。

我现在正在尝试将哈希表保存在文件中。 关于我写的代码我几乎没有问题:

  1. 代码无效,有些错误我不明白:
  2. 线程中的异常" main" java.io.EOFException的

    at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
    at java.io.ObjectInputStream.<init>(Unknown Source)
    at Q2.MainPanel.updateHashFromFile(MainPanel.java:133)
    at Q2.MainPanel.<init>(MainPanel.java:46)
    at Q2.Main.main(Main.java:13)
    
    1. eclipse总是警告我要为每个写一些处理文件的方法添加抛出。我认为这样做的方式是正确的吗?

    2. 是否像我一样将FileInputStream,ObjectInputStream,File声明为全局参数?或者有更多推荐的方式吗?

    3. 您认为在同一个类中一起编写面板和GUI处理和数据以及像我一样保存处理的好方法吗?或者将这些分成几类更好?

    4. 这是代码:

      package Q2;
      import java.awt.BorderLayout;
      import java.awt.Font;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutputStream;
      import java.util.Hashtable;
      
      import javax.swing.JButton;
      import javax.swing.JComboBox;
      import javax.swing.JPanel;
      import javax.swing.JTextArea;
      
      public class MainPanel extends JPanel{
      
          private String[] days = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
          private String[] months = {"1","2","3","4","5","6","7","8","9","10","11","12"};
          private String[] years = {"2014","2015","2016","2017","2018"};
          private Font myFont = new Font("david", Font.BOLD, 24);
          JButton btnSave, btnShow;
          JComboBox daysBox,yearsBox,monthsBox;
          private static Hashtable<MyDate, String> diary;
          private JTextArea textArea;
          private static File file;
          private static FileInputStream in;
          private static FileOutputStream out;
          private static ObjectInputStream streamIn;
          private static ObjectOutputStream streamOut;
      
          //Constructor for main panel with BorderLayout with panels inside
          public MainPanel () throws IOException, ClassNotFoundException{
              this.setLayout(new BorderLayout());
              add(getDateButtons(),BorderLayout.NORTH);
              textArea = new JTextArea();
              textArea.setFont(myFont);
              add(textArea, BorderLayout.CENTER);
              add(getSaveShowButtons(),BorderLayout.SOUTH);
      
              file = new File("MyDiary");
              updateHashFromFile();
      
      
              diary = new Hashtable<MyDate, String>();
          }
      
          //create and return the NORTH date buttons panel
          private JPanel getDateButtons(){
              JPanel dateButtons = new JPanel();
      
              //create and add the days JCombobox
              daysBox = new JComboBox(days);
              daysBox.setFont(myFont);
              dateButtons.add(daysBox);
      
              //create and add the months JCombobox
              monthsBox = new JComboBox(months);
              monthsBox.setFont(myFont);
              dateButtons.add(monthsBox);
      
              //create and add the year JCombobox
              yearsBox = new JComboBox(years);
              yearsBox.setFont(myFont);
              dateButtons.add(yearsBox);
      
              return dateButtons;
          }
      
          //
          private JPanel getSaveShowButtons(){
              JPanel saveShowButtons = new JPanel();
              ButtonListener lis = new ButtonListener();
      
              btnSave = new JButton("save");
              btnSave.addActionListener(lis);
              btnSave.setFont(myFont);
              saveShowButtons.add(btnSave);
      
              btnShow = new JButton("show");
              btnShow.addActionListener(lis);
              btnShow.setFont(myFont);
              saveShowButtons.add(btnShow);
      
              return saveShowButtons;
      
          }
      
          private class ButtonListener implements ActionListener{
      
      
              @Override
              public void actionPerformed(ActionEvent e) {
                  if (e.getSource()==btnSave){
                      int day = Integer.parseInt((String)daysBox.getSelectedItem());
                      int month = Integer.parseInt((String)monthsBox.getSelectedItem());
                      int year = Integer.parseInt((String)yearsBox.getSelectedItem());
                      MyDate date = new MyDate(day, month, year);
                      System.out.println(date);
                      diary.put(date,textArea.getText());
                      textArea.setText(null);
                      try {
                          updateHashToFile();
                      } catch (IOException e1) {
                          // TODO Auto-generated catch block
                          e1.printStackTrace();
                      }
                  }
                  if (e.getSource()==btnShow){
                      int day = Integer.parseInt((String)daysBox.getSelectedItem());
                      int month = Integer.parseInt((String)monthsBox.getSelectedItem());
                      int year = Integer.parseInt((String)yearsBox.getSelectedItem());
                      MyDate date = new MyDate(day, month, year);
                      String s = diary.get(date);
                      if (s!=null)
                          textArea.setText(s+" ");
                      else textArea.setText(" ");
                  }
      
              }
          }
      
          @SuppressWarnings("unchecked")
          private static void updateHashFromFile() throws IOException, ClassNotFoundException{
              if(!file.exists())
                  file.createNewFile();
              else {
                  in = new FileInputStream(file);
                  streamIn = new ObjectInputStream(in);
                  diary = (Hashtable<MyDate, String>)streamIn.readObject();
              }
      
          }
      
          //update the file with the new hash table diary data
          private static void updateHashToFile() throws IOException{
              out = new FileOutputStream(file);
              streamOut = new ObjectOutputStream(out);
              streamOut.writeObject(diary);
          }
      }
      

      MyDate类代码:

      package Q2;
      
      public class MyDate {
      
          private static int[] numOfDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //Number of days on each month
          private int day;
          private int month;
          private int year;
      
          //Constructor for date object
          public MyDate(int day, int month, int year){
              if(day<=numOfDays[month-1]){ //In case chosen day that not exist in the month the last day of the month will be chosen
                  this.day = day;
              }else this.day = numOfDays[month-1];
              this.month = month;
              this.year = year;
          }
      
          //@override toString
          public String toString(){
              return this.day+"/"+ this.month+"/"+this.year;
          }
      
          //@override equals
          public boolean equals(Object other){
              if(this.day==((MyDate)other).day && this.month==((MyDate)other).month && this.year==((MyDate)other).year)
                  return true;
              return false;
          }
      
      
          public int hashCode() {
              return ((day * 31) + month) * 31 + year; 
          }
      }
      

      主类代码:

      package Q2;
      import java.io.IOException;
      
      import javax.swing.JFrame;
      
      public class Main {
      
          public static void main(String[] args) throws IOException, ClassNotFoundException{
              JFrame frame = new JFrame("Diary");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setSize(700, 700);
              frame.setLocationRelativeTo(null);
              MainPanel mainPanel = new MainPanel();
              frame.add(mainPanel);
      
              frame.setVisible(true);
          }
      }
      

1 个答案:

答案 0 :(得分:0)

  1. 我没有收到任何警告,但ClassNotFoundException异常看起来没用。

  2. 避免对流使用静态变量。您可以在此特定代码中本地声明它们,但这不是规则。相反,你可以声明静态最终的日期,月份和年份,因为它们是常量而且永远不会改变。

  3. 这是您的选择,取决于代码最终的清晰程度。

  4. 请务必关闭蒸汽。

    这是修改后的代码和我的建议。我暂时用java.util.Date替换了MyDate,所以我可以编译代码,你可以忽略它。

    import java.awt.BorderLayout;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.FileInputStream;
    //import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.Hashtable;
    
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    
    public class MainPanel extends JPanel{
    
        private static final String[] days = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
        private static final String[] months = {"1","2","3","4","5","6","7","8","9","10","11","12"};
        private static final String[] years = {"2014","2015","2016","2017","2018"};
        private static final Font myFont = new Font("david", Font.BOLD, 24);
        JButton btnSave, btnShow;
        JComboBox daysBox,yearsBox,monthsBox;
        private Hashtable<java.util.Date, String> diary;
        private JTextArea textArea;
        private File file;
    
        //Constructor for main panel with BorderLayout with panels inside
        public MainPanel () throws IOException, ClassNotFoundException{
            this.setLayout(new BorderLayout());
            add(getDateButtons(),BorderLayout.NORTH);
            textArea = new JTextArea();
            textArea.setFont(myFont);
            add(textArea, BorderLayout.CENTER);
            add(getSaveShowButtons(),BorderLayout.SOUTH);
    
            file = new File("MyDiary");
            updateHashFromFile();
    
    
            diary = new Hashtable<java.util.Date, String>();
        }
    
        //create and return the NORTH date buttons panel
        private JPanel getDateButtons(){
            JPanel dateButtons = new JPanel();
    
            //create and add the days JCombobox
            daysBox = new JComboBox(days);
            daysBox.setFont(myFont);
            dateButtons.add(daysBox);
    
            //create and add the months JCombobox
            monthsBox = new JComboBox(months);
            monthsBox.setFont(myFont);
            dateButtons.add(monthsBox);
    
            //create and add the year JCombobox
            yearsBox = new JComboBox(years);
            yearsBox.setFont(myFont);
            dateButtons.add(yearsBox);
    
            return dateButtons;
        }
    
        //
        private JPanel getSaveShowButtons(){
            JPanel saveShowButtons = new JPanel();
            ButtonListener lis = new ButtonListener();
    
            btnSave = new JButton("save");
            btnSave.addActionListener(lis);
            btnSave.setFont(myFont);
            saveShowButtons.add(btnSave);
    
            btnShow = new JButton("show");
            btnShow.addActionListener(lis);
            btnShow.setFont(myFont);
            saveShowButtons.add(btnShow);
    
            return saveShowButtons;
    
        }
    
        private class ButtonListener implements ActionListener{
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource()==btnSave){
                    int day = Integer.parseInt((String)daysBox.getSelectedItem());
                    int month = Integer.parseInt((String)monthsBox.getSelectedItem());
                    int year = Integer.parseInt((String)yearsBox.getSelectedItem());
                    java.util.Date date = new java.util.Date(day, month, year);
                    System.out.println(date);
                    diary.put(date,textArea.getText());
                    textArea.setText(null);
                    try {
                        updateHashToFile();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
                if (e.getSource()==btnShow){
                    int day = Integer.parseInt((String)daysBox.getSelectedItem());
                    int month = Integer.parseInt((String)monthsBox.getSelectedItem());
                    int year = Integer.parseInt((String)yearsBox.getSelectedItem());
                    java.util.Date date = new java.util.Date(day, month, year);
                    String s = diary.get(date);
                    if (s!=null)
                        textArea.setText(s+" ");
                    else textArea.setText(" ");
                }
    
            }
        }
    
        @SuppressWarnings("unchecked")
        private void updateHashFromFile() throws IOException, ClassNotFoundException{
            if(!file.exists())
                file.createNewFile();
            else {
                FileInputStream in = new FileInputStream(file);
                ObjectInputStream streamIn = new ObjectInputStream(in);
                diary = (Hashtable<java.util.Date, String>)streamIn.readObject();
                streamIn.close();
            }
    
        }
    
        //update the file with the new hash table diary data
        private void updateHashToFile() throws IOException{
            FileOutputStream out = new FileOutputStream(file);
            ObjectOutputStream streamOut = new ObjectOutputStream(out);
            streamOut.writeObject(diary);
            streamOut.close();
        }
    }