USQ*_*Q91 3 java arrays oop java-8 java-stream
我正在从文件中读取输入,其中每行具有相等数量的字符。
oooooooooo 哦哦 ro rrrroooooo rrrrrtoooo
我正在尝试将对象添加到Square [] []类型的2D数组中。Square是具有SquareOne,SquareTwo,SquareThree等多种实现的接口。
无论文件的位置为“ o”,我都打算为该位置添加一个SquareOne对象。同样,“ t”为SquareTwo,“ r”为SquareThree,依此类推。例如,square [0] [0]应该具有SquareOne obj,而[0] [2]应该具有SquareTwo obj。
如何使用Java 8 Stream实现它?
我已经读过这个文件的字符并将它们全部添加到char [] []数组中。但是,我想将基于字符的对象添加到Square [] []。
public static char[][] addFromFileToSquareArray(String filePath){
char[][] doubleChar = new char[5][10];
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
doubleChar = stream
.map(x->x.replaceAll(" ",""))
.map(String::toCharArray).toArray(char[][]::new);
} catch (IOException e) {
e.printStackTrace();
}
return doubleChar;
}
Run Code Online (Sandbox Code Playgroud)
One approach would be to stream over the characters of each string, like
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;
}
Run Code Online (Sandbox Code Playgroud)
Generally, I’d prefer to declare throws IOException at the method to enforce the caller to deal with potential exceptions reasonably. At least, you should not catch excpeptions, just to print them and return a result value that will cause other problems at a later time (like an uninitialized array like in your original code).
Since the mapping seems to be intended to be extensible, it’s worth moving it into a method of its own, e.g.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
and use
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;
}
Run Code Online (Sandbox Code Playgroud)
I placed the squareFor method right in the Square interface. Otherwise, you have to change the class in the Square::squareFor reference.
Alternatively, you could use a 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();
}
Run Code Online (Sandbox Code Playgroud)
Here, the line gets split into substrings uses the spaces as delimiter, which will intrinsically eliminate them, so there’s no filter operation needed afterwards. But your life would be much easier if you could redefine your input format to not contain these spaces.
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |