Java record,switch,sealed interface 新特性初尝试

场景:

guess的字母,是否在hidden的单词中的正确位置。匹配正位,大写,匹配异位,小写,不匹配.

传统写法:

public record Wordle2(String hidden) {
    public String guess(String guess){
        StringBuilder result = new StringBuilder();
        // 确保一个字母,不被重复匹配
        boolean[] used = new boolean[hidden.length()];
        for(int i=0;i<guess.length();i++){
            // 正确位置正确字母
            if(guess.codePointAt(i) == this.hidden.codePointAt(i)){
                // 转成大写
                result.append(Character.toString(guess.codePointAt(i)).toUpperCase(Locale.ROOT));
                used[i] = true; // i位已被匹配
            }else{
                boolean found = false; //当前位置是否找到
                for (int j = 0;j<hidden.length();j++){
                    if(used[j]){ // j位已被匹配,跳过当次
                        continue;
                    }
                    // 非正确位置
                    if(i != j &&
                            // 隐藏字母,不应与猜的字母匹配
                            guess.codePointAt(j) != this.hidden.codePointAt(j) &&
                            // 正确字母
                            guess.codePointAt(i) == this.hidden.codePointAt(j)){
                        // 小写放入结果
                        result.append(Character.toString(guess.codePointAt(i)));
                        found = true; //当前位置已找到
                        used[j] = true; // j位已被匹配
                        break; // 匹配则跳出循环
                    }
                }
                if(!found){ //当前位置未找到
                    result.append(".");
                }
            }
        }
        return result.toString();
    }

新特性优化写法

public record Wordle(String hiddenAsString) {
    record Guess(String guess){
        public int length() {
            // 委托模式
            return this.guess.length();
        }
        public int codePointAt(int index) {
            return this.guess.codePointAt(index);
        }
        // 检查这个字符和隐藏的单词
        public GuessWithIndex checkCharacterAtPosition(int index) {
            return new GuessWithIndex(this, index);
        }

        // 流
        public LetterStream checkAgainst(Hidden hidden) {
            return new LetterStream(IntStream.range(0, length())
                    //switch模式匹配,允许添加行为到一个类而不触及它,也无需修改
                    //添加行为有两种方式:
                    //1. 对非final的类扩展
                    //2. 组合(需创建一些新类型,以便将一些方法调用委托给组合的对象)
                    .mapToObj(index -> checkCharacterAtPosition(index).with(hidden)));
        }
    }

    record LetterStream(Stream<Letter> stream){
        // Function 接受 Letter 返回 String
        String replaceEachLetterWith(Function<Letter, String> mapper){
            return stream.map(mapper)
                         // 组成一个字符串
                         .collect(Collectors.joining());
        }
    }

    record Hidden(String hidden, boolean[] used){
        Hidden(String hidden){
            this(hidden, new boolean[hidden.length()]);
        }
        public int codePointAt(int index) {
            return this.hidden.codePointAt(index);
        }
        public int length() {
            return this.hidden.length();
        }

        private boolean match(GuessWithIndex guessWithIndex, int indexGuess, int indexHidden) {
            if(used[indexHidden]){
                return false;
            }
            // 猜测的字母,与隐藏字母比较
            boolean match = guessWithIndex.guess.codePointAt(indexGuess) == codePointAt(indexHidden);
            if(match){
                // 则表示该位置已被匹配成功,不再重复匹配
                used[indexHidden] = true;
            }
            // 返回是否匹配
            return match;
        }
    }

    record GuessWithIndex(Guess guess, int index) {
        // 匹配,正确位
        public boolean thatIsWellPlacedIn(Hidden hidden){
            return hidden.match(this, index, index);
        }
        // 匹配,非正确位
        public boolean thatIsNotWellPlacedIn(Hidden hidden){
            return IntStream.range(0, hidden.length()) // 整数流
                    .filter(i -> index != i) //过滤匹配index的索引位
                    .filter(i -> guess.codePointAt(i) != hidden.codePointAt(i)) //过滤出字母匹配的位置
                    .anyMatch(i -> hidden.match(this, index, i)); //字母匹配,但不在应有位置
        }
        // 返回switch中选择器变量的类型
        public Letter with(Hidden hidden) {
            if(thatIsWellPlacedIn(hidden)){
                return new WELL_PLACED(this.guess.codePointAt(this.index));
            }else if (thatIsNotWellPlacedIn(hidden)){
                return new NOT_WELL_PLACED(this.guess.codePointAt(this.index));
            }else {
                return new ABSENT();
            }
        }
    }
    sealed interface Letter // 封闭类
    permits WELL_PLACED,NOT_WELL_PLACED,ABSENT{} //只允许这些record实现
    record WELL_PLACED(int codePoint) implements Letter{ }
    record NOT_WELL_PLACED(int codePoint) implements Letter{}
    record ABSENT() implements Letter{}

    public String guess(String guessStr){
        Guess guess = new Guess(guessStr);
        Hidden hidden = new Hidden(hiddenAsString);
        return guess.checkAgainst(hidden)
                    .replaceEachLetterWith(
                        l -> switch (l) {
                            case WELL_PLACED letter ->
                                    Character.toString(letter.codePoint()).toUpperCase();
                            case NOT_WELL_PLACED letter ->
                                    Character.toString(letter.codePoint());
                            case ABSENT ignored ->
                                    ".";
                        }
                    );
    }
}
@Test
    public void wordle(){
        assertEquals(new Wordle2("aaaaa").guess("bbbbb"),".....");
        assertEquals(new Wordle2("aaaaa").guess("bbabb"),"..A..");
        assertEquals(new Wordle2("abbbb").guess("ccacc"),"..a..");
        assertEquals(new Wordle2("abbbb").guess("cccca"),"....a");
        assertEquals(new Wordle2("abbbb").guess("accca"),"A....");
        assertEquals(new Wordle2("aaabb").guess("cccaa"),"...aa");
        assertEquals(new Wordle2("aaabb").guess("aaacc"),"AAA..");
        assertEquals(new Wordle2("aabbb").guess("accaa"),"A..a.");


        assertEquals(new Wordle("aaaaa").guess("bbbbb"),".....");
        assertEquals(new Wordle("aaaaa").guess("bbabb"),"..A..");
        assertEquals(new Wordle("abbbb").guess("ccacc"),"..a..");
        assertEquals(new Wordle("abbbb").guess("cccca"),"....a");
        assertEquals(new Wordle("abbbb").guess("accca"),"A....");
        assertEquals(new Wordle("aaabb").guess("cccaa"),"...aa");
        assertEquals(new Wordle("aaabb").guess("aaacc"),"AAA..");
        assertEquals(new Wordle("aabbb").guess("accaa"),"A..a.");
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值