Один из подходов заключается в потоковой передаче по символам каждой строки, например
public static Square[][] addFromFileToSquareArray(String filePath) {
Square[][] squares;
try(Stream<String> stream = Files.lines(Paths.get(filePath))) {
squares = stream
.filter(line -> !line.isEmpty())
.map(line -> line.chars()
.filter(ch -> ch != ' ')
.mapToObj(ch -> ch =='o'? new SquareOne():
ch == 't'? new SquareTwo(): new SquareThree())
.toArray(Square[]::new) )
.toArray(Square[][]::new);
} catch(IOException e) {
throw new UncheckedIOException(e);
}
return squares;
}
Как правило, я бы предпочел объявить throws IOException
в методе, чтобы заставить вызывающую сторону разумно обрабатывать потенциальные исключения,По крайней мере, вы не должны перехватывать исключения, просто печатать их и возвращать значение результата, которое позже вызовет другие проблемы (например, неинициализированный массив, как в исходном коде).
Поскольку отображение, по-видимому,чтобы быть расширяемым, стоит перенести его в собственный метод, например
public static Square squareFor(int type) {
switch(type) {
case 'o': return new SquareOne();
case 't': return new SquareTwo();
case 'r': return new SquareThree();
default: throw new IllegalArgumentException("type "+(char)type);
}
}
и использовать
public static Square[][] addFromFileToSquareArray(String filePath) {
Square[][] squares;
try(Stream<String> stream = Files.lines(Paths.get(filePath))) {
squares = stream
.filter(line -> !line.isEmpty())
.map(line -> line.chars()
.filter(ch -> ch != ' ')
.mapToObj(Square::squareFor)
.toArray(Square[]::new) )
.toArray(Square[][]::new);
} catch(IOException e) {
throw new UncheckedIOException(e);
}
return squares;
}
Я поместил метод squareFor
прямо вSquare
интерфейс.В противном случае вы должны изменить класс в справочнике Square::squareFor
.
В качестве альтернативы вы можете использовать Map
public static Square[][] addFromFileToSquareArray(String filePath) {
Square[][] squares;
Pattern spaces = Pattern.compile(" ");
try(Stream<String> stream = Files.lines(Paths.get(filePath))) {
squares = stream
.filter(line -> !line.isEmpty())
.map(line -> spaces.splitAsStream(line)
.map(Square::squareFor)
.toArray(Square[]::new) )
.toArray(Square[][]::new);
} catch(IOException e) {
throw new UncheckedIOException(e);
}
return squares;
}
static final Map<String,Supplier<Square>> MAP = Map.of(
"o", SquareOne::new,
"t", SquareTwo::new,
"r", SquareThree::new
);
public static Square squareFor(String type) {
Supplier<Square> s = MAP.get(type);
if(s == null) throw new IllegalArgumentException("type "+type);
return s.get();
}
Здесь строка разбивается на подстрокииспользует пробелы в качестве разделителя, который по сути их устраняет, поэтому в дальнейшем не требуется операция filter
.Но ваша жизнь была бы намного проще, если бы вы могли переопределить свой формат ввода, чтобы не содержать эти пробелы.