Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Десериализация LinkedHashMap


Автор: Junky2255 25.3.2012, 23:59
Доброго времени суток. Такая проблема. Имеется двухуровневый кеш, реализованный с помощью LinkedHashMap. Когда кол-во пар ключ-значение превышает указанное, с момощью переопределенного метода removeEldestEntry сериализую самыу старую пару ключ-значение, записывая в файл:
Код


protected boolean removeEldestEntry(Map.Entry eldest) {
            if (size() > maxCache){
                ObjectOutputStream oos = null;
                try {
                    oos = new ObjectOutputStream(new FileOutputStream("E:/cacheBox.cach"));
                    oos.writeObject(eldest.getValue());
                    oos.writeObject(eldest.getKey());
                    oos.flush();
                    oos.close();
                } catch (IOException ex) {
                    Logger.getLogger(MyCache.class.getName()).log(Level.SEVERE, null, ex);
                }
                return true;
            } else return false;


Далее в ступоре. При обращении к записям сначала проверяю имеются ли они в мапе. Если нет, нужно десериализовать искомую пару ключ-значение. Честно сказал, вообще не представляю как это сделать. Нашел такое обобщенное решение:
Цитата

берем стандартный LinkedHashMap - создаем с параметром accessOrder=true
переопределяем метод removeEldestEntry(Map.Entry) - сериализуем объект, возвращаем true
переопределяем метод get(Object o) - чтоб в случае, когда объект не найден (get, containsKey) лез в сериализацию (и засовывал объект в map) 

Только не могу представить как это сделать. Не могу понять как он найдет нужную пару из всех сериализованных обхектов. Есть ли методы, алгоритмы? И вообще при сериализации эти две операции сохранят связь между ключом и значением?
Код

oos.writeObject(eldest.getValue());
oos.writeObject(eldest.getKey());

Переваривал примеры с сериализацией. В них просто создавались два класса. В одном устанавливались поля в определенные значение. Второй класс реализовывал интерфейс Serializable и проводил саму сериализацию. При этом явно создавался объект класса еще в исходнике. Не могу понять как перенсести это на мой случай, когда строки создаются во время работы приложения. 
Простите, я еще только учусь, многого просто в голове уложить не могу, часто не понимаю сути. Заранее извиняюсь, если выражаюсь топорно. Все не со зла. И заранее очень благодарен всем тем, кто поможет. Спасибо )))

Добавлено через 11 минут и 6 секунд
В пределах мапы провожу проверку таким образом (проверка проводится в теле метода actionPerformed обработчика событий):
Код

String s = getName.getText();
                s = s.toUpperCase(); //специально перевожу, чтобы при поиске по ключу избежать расходимости при введении имени с прописной и строчной буквы
                if (box.containsKey(s)) getPhone.setText(s + " number of phone is: " + (String)box.get(s));

Автор: Junky2255 26.3.2012, 00:30
Код

public class serializeMap {

    public static void main(String[] args) throws IOException {
       HashMap hmap=new HashMap();
       HashMap hmapout=new HashMap();
       hmap.put("a", "b");
  try {
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream("/MyDir/serialize/fileMap.ser"));
        out.writeObject(hmap);
        out.close();


    } catch (IOException e) {
    }
     try {
        
        File file = new File("/MyDir/serialize/fileMap.ser");
        ObjectInputStream ins = new ObjectInputStream(new FileInputStream(file));
        
        hmapout= (HashMap) ins.readObject();
        ins.close();

    } catch (ClassNotFoundException e) {
    } catch (IOException e) {
    }
    System.out.println(hmapout);
    }

}

Вот еще пример. Сериализуют полностью карту. Тоже создали явно два объекта. Все ясно. А как вытащить только одно нужное значение из карты и десериализовать его неясно уже.

Автор: LSD 26.3.2012, 14:55
Цитата(Junky2255 @  26.3.2012,  01:30 Найти цитируемый пост)
как вытащить только одно нужное значение из карты и десериализовать его неясно уже

Никак. Сериализация предназначена для сохранения и восстановления объекта целиком, а не отдельных частей объекта.

Автор: Junky2255 27.3.2012, 10:14
Спасибо всем кто откликнулся. Вопрос решился созданием отдельной директории. В ней при удалении старых элементов таблицы создается отдельный файл (имя == индекс), в файл сериализуется значение )))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)