У вас есть несколько решений, все в зависимости от ввода:
Вы можете выполнять итерацию до тех пор, пока поток не будет полностью использован: я думаю, что это худшее решение из тех, что я вам предоставляю.Это хуже, потому что вы проверяете, достигнуто ли EOF, в то время как вы должны знать, когда вы закончите (например, неверный формат вашего файла).
Set<Name> result = new HashSet<>();
try {
for (;;) {
result.add((Name)objectInputStream.readObject());
}
} catch (EOFException e) {
// End of stream
}
return result;
При создании ввода, сериализовать коллекцию и вызвать на нее readObject()
.Serialization
должен иметь возможность читать коллекцию, если каждый объект реализует Serializable
.
static void write(Path path, Set<Name> names) throws IOException {
try (OutputStream os = Files.newOutputStream(path);
ObjectOutputStream oos = new ObjectOutputStream(os)) {
oos.writeObject(names);
}
}
static Set<Name> read(Path path) throws IOException {
try (InputStream is = Files.newInputStream(path);
ObjectInputStream ois = new ObjectInputStream(is)) {
// WARN Files.newInputStream is not buffered; ObjectInputStream might
// be buffered (I don't remember).
return (Set<Name>) ois.readObject();
}
}
При создании ввода можно добавить int
, указывающийномер объекта для чтения и итерации по нему: это полезно в том случае, если вы действительно не заботитесь о коллекции (HashSet
).Полученный файл будет меньше (потому что у вас не будет метаданных HashSet
).
int result = objectInputStream.readInt();
Name[] names = new Name[result]; // do some check on result!
for (int i = 0; i < result; ++i) {
names[i] = (Name) objectInputStream.readObject();
}
Кроме того, Set
хороши, но, поскольку они удаляют дубликаты, используя hashCode()
/ equals()
вы можете получить меньше объектов, если ваше определение equals
/ hashCode
изменилось после факта (пример: ваш Name
был чувствителен к регистру, а теперь нет, например: new Name("AA").equals(new Name("aa"))
).