자바 스트림을 사용하여 입력 파일의 문자를 기반으로 2 차원 배열에 객체를 추가하는 방법

USQ91 :

나는 각 줄의 문자와 동일한 번호를 가진 파일에서 입력을 읽고 있어요.

ootooooooo

ooooooo T oo의

rrroooo T oo의

rrrroooooo

rrrrrtoooo

나는 광장 [] [] 타입의 2 차원 배열에 객체를 추가하려고 해요. 스퀘어 SquareOne, SquareTwo, SquareThree 등과 같은 여러 구현와 인터페이스

파일이 'O'이 어디든지, 그 위치에 대한 SquareOne 개체를 추가 할 계획입니다. 마찬가지로 SquareTwo 't'에 대한, SquareThree 'R'에 대한 등등. 예컨대 광장 [0]의 [0] SquareOne OBJ하면서 0]을 가져야한다 [2] SquareTwo OBJ 가져야한다.

어떻게 자바 8 스트림을 사용하여 달성 할 수 있습니까?

나는이 파일의 문자를 읽어와 문자 [] [] 배열에 그들 모두를 추가로까지로 왔어요. 하지만 그 대신, 나는 [] [] 광장에있는 문자를 기반으로 개체를 추가하려고합니다.

 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;
    }
홀거 :

한 가지 방법은 같은 각 문자열의 문자를 통해 스트리밍하는 것

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합리적으로 잠재적 인 예외를 처리 할 수있는 호출을 적용하는 방법에. 적어도, 당신은 excpeptions을 잡을해야 그냥 인쇄하고 (원래 코드에서와 같이 초기화되지 않은 배열과 같은) 나중에 다른 문제를 야기하는 결과 값을 반환합니다.

매핑이 확장 가능하도록 구성하는 것 때문에, 그것은 가치 자체, 예를 들면하는 방법으로 이동입니다

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이후에 필요한 작업. 이 공백을 포함 할 수 없습니다에 당신이 당신의 입력 형식을 다시 정의 할 수 있다면 그러나 당신의 인생이 훨씬 쉬울 것이다.

추천

출처http://43.154.161.224:23101/article/api/json?id=200897&siteId=1