最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java解釋器模式

 更新時(shí)間:2021年10月14日 10:11:33   作者:KnightHONG  
這篇文章主要介紹了Java基于解釋器模式實(shí)現(xiàn)定義一種簡單的語言功能,簡單描述了解釋器模式的概念、功能及Java使用解釋器模式定義一種簡單語言的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下

​ **請注意!請注意?。?!**今天講給大家講解非?!?strong>有用”的設(shè)計(jì)模式,解釋器模式?。。?/p>

​ 設(shè)計(jì)模式有三大種類,一種是創(chuàng)建型模式,一種是結(jié)構(gòu)型模式,最后一種是行為性模式,那么解釋器模式屬于哪一種呢?帶領(lǐng)大家一起來了解學(xué)習(xí)解釋器模式!

​ 本次介紹圍繞著以下五點(diǎn)展開。什么是解釋器模式?用來做什么?怎么做?有哪些優(yōu)點(diǎn)?有哪些不足?

​ 解釋器模式顧名思義,就是用來定義解釋。

​ 給定一種特定語言,這個(gè)語言有特定的文法,解釋器可以解釋這個(gè)語言中的句子含義。即解釋器提供一種語言,如java,同時(shí)它也提供一種手段去解析java語言寫出來的代碼。

​ 大家可能也會(huì)想到這就是類似編譯原理,一個(gè)算術(shù)表達(dá)式要經(jīng)過詞法分析,語法分析,構(gòu)建語法樹啥的;還有正則表達(dá)式;SQL解析,編譯器等等,其實(shí)都是解析式模式的一種實(shí)現(xiàn)。

​ 那怎么做?一個(gè)是說要有像編譯原理中的終結(jié)符非終結(jié)符,構(gòu)建一顆語法樹。同時(shí)需要有一個(gè)環(huán)境類,來管理輸入和輸出

​ 這里我們舉一個(gè)例子,輸入一個(gè)表達(dá)式a+b-c+d-e,同時(shí)給這5個(gè)變量賦值,計(jì)算出它的值。那么使用解釋器模式要如何實(shí)現(xiàn)?

​ 我們?yōu)榻忉屍鞫x一個(gè)抽象解釋類Expression,所有的流轉(zhuǎn)通過interpreter方法實(shí)現(xiàn)。

​ 上下文管理輸入輸出使用一個(gè)HashMap去實(shí)現(xiàn)。

​ 定義符號(hào)解釋類SymbolExpression,加法解釋類AddExpreesion,減法解釋類SubExpression。

類圖:

在這里插入圖片描述

具體代碼實(shí)現(xiàn):

public abstract class Expression {

    // map中攜帶了表達(dá)式中的變量名(key) 和 對(duì)應(yīng)的值(value)
    public abstract int interpreter(Map<String, Integer> var);

}

public class VarExpression extends Expression {

    // 表達(dá)式中對(duì)應(yīng)的變量名
    String key;

    public VarExpression(String var) {
        this.key = var;
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        return var.get(key);
    }
}

public class SymbolExpression extends Expression {

    // +或-符號(hào) 左右兩邊的表達(dá)式
    Expression var1;
    Expression var2;

    public SymbolExpression(Expression var1, Expression var2) {
        this.var1 = var1;
        this.var2 = var2;
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        // 實(shí)現(xiàn)抽象方法
        // 該類不需要用到該方法 默認(rèn)返回0
        return 0;
    }
}

public class AddExpression extends SymbolExpression {

    public AddExpression(Expression var1, Expression var2) {
        super(var1, var2);
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        return var1.interpreter(var) + var2.interpreter(var);
    }
}

public class SubExpression extends SymbolExpression {

    public SubExpression(Expression var1, Expression var2) {
        super(var1, var2);
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        return var1.interpreter(var) - var2.interpreter(var);
    }

}

public class Calculator {

    // 表達(dá)式
    private Expression expression;

    // 解析出表達(dá)式
    public Calculator(String expStr) {
        Stack<Expression> stack = new Stack<>();
        Expression left, right = null;
        char[] expStrCharArray = expStr.toCharArray();

        for(int i = 0; i < expStrCharArray.length; i++) {
            switch (expStrCharArray[i]) {
                case '+':// 加法運(yùn)算 獲取左邊表達(dá)式 右邊數(shù)值
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(expStrCharArray[++i]));
                    stack.push(new AddExpression(left, right));
                    break;
                case '-':// 減法運(yùn)算 獲取左邊表達(dá)式 右邊數(shù)值
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(expStrCharArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default:// 表達(dá)式中的變量
                    stack.push(new VarExpression(String.valueOf(expStrCharArray[i])));
                    break;
            }
        }
        // 最后會(huì)獲得被Expression包裝起來的一個(gè)表達(dá)式
        this.expression = stack.pop();
    }

    // 計(jì)算結(jié)果
    public int run(Map<String, Integer> var) {
        return this.expression.interpreter(var);
    }
}

public class Client {

    public static void main(String[] args) throws IOException {
        String expStr = getExpStr();
        Map<String, Integer> var = getValue(expStr);
        Calculator calculator = new Calculator(expStr);
        System.out.println("運(yùn)算結(jié)果:" + expStr + "=" + calculator.run(var));
    }

    //獲得表達(dá)式
    public static String getExpStr() {
        return "a+b-c+d-e";
    }

    //獲得值映射
    public static HashMap<String, Integer> getValue(String expStr) throws IOException {
        HashMap<String, Integer> map = new HashMap<>();

        for(char ch : expStr.toCharArray()) {
            if(ch != '+' && ch != '-' ) {
                if(! map.containsKey(String.valueOf(ch))) {
                    System.out.print("請輸入" + String.valueOf(ch) + "的值:");
                    String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    map.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }

        return map;
    }

}


結(jié)果

/*
請輸入a的值:1
請輸入b的值:3
請輸入c的值:5
請輸入d的值:7
請輸入e的值:9
運(yùn)算結(jié)果:a+b-c+d-e=-3
*/

​ 或許看代碼會(huì)有點(diǎn)云里霧里,希望大家能手動(dòng)敲一遍,或許會(huì)對(duì)整個(gè)過程有更進(jìn)一步的理解,在編碼的同時(shí)不斷思考,提升自我。

​ 很容易發(fā)現(xiàn)解釋器模式是屬于行為性模式的一種,這種模式更關(guān)注對(duì)象之間的通信。

​ 解釋器模式優(yōu)點(diǎn),結(jié)構(gòu)清晰,可拓展性好。但也有缺點(diǎn),一般用在比較底層場景,平常敲代碼可使用的場景比較少,并且解釋器模式采用的是遞歸的方式,當(dāng)語言比較長,性能不高;同時(shí)如果文法比較復(fù)雜,也需要更多的相應(yīng)解釋類。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Intellij Idea部署OpenCV 4.0.0環(huán)境

    Intellij Idea部署OpenCV 4.0.0環(huán)境

    這篇文章主要為大家詳細(xì)介紹了Intellij Idea部署OpenCV 4.0.0環(huán)境,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • 詳解Java設(shè)計(jì)模式之外觀模式

    詳解Java設(shè)計(jì)模式之外觀模式

    在Java開發(fā)中,設(shè)計(jì)模式是一種十分常見的編程思想,它可以幫助我們解決很多實(shí)際開發(fā)中的問題,本篇文章將介紹一種常見的設(shè)計(jì)模式——外觀模式,并結(jié)合實(shí)際的開發(fā)場景進(jìn)行講解,需要的朋友可以參考下
    2023-06-06
  • Java的四種常見線程池及Scheduled定時(shí)線程池實(shí)現(xiàn)詳解

    Java的四種常見線程池及Scheduled定時(shí)線程池實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java的四種常見線程池及Scheduled定時(shí)線程池實(shí)現(xiàn)詳解,在Java中,我們可以通過Executors類來創(chuàng)建ScheduledThreadPool,Executors類提供了幾個(gè)靜態(tài)方法來創(chuàng)建不同類型的線程池,包括ScheduledThreadPool,需要的朋友可以參考下
    2023-09-09
  • JDK源碼中一些實(shí)用的“小技巧”總結(jié)

    JDK源碼中一些實(shí)用的“小技巧”總結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于JDK源碼中一些實(shí)用的“小技巧”,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用jdk源碼具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • 詳解Java的Spring框架中的注解的用法

    詳解Java的Spring框架中的注解的用法

    這篇文章主要介紹了Java的Spring框架中的注解的用法,包括對(duì)Java bean的定義的作用介紹,需要的朋友可以參考下
    2015-11-11
  • springboot使用log4j2異步日志提升性能的實(shí)現(xiàn)方式

    springboot使用log4j2異步日志提升性能的實(shí)現(xiàn)方式

    這篇文章主要介紹了springboot使用log4j2異步日志提升性能,異步日志實(shí)現(xiàn)方式:將日志存入一個(gè)單獨(dú)的隊(duì)列中,有一個(gè)單獨(dú)的線程從隊(duì)列中獲取日志并寫入磁盤文件,需要的朋友可以參考下
    2022-05-05
  • java對(duì)象類型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)

    java對(duì)象類型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)

    下面小編就為大家?guī)硪黄猨ava對(duì)象類型轉(zhuǎn)換和多態(tài)性(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Spring使用event-stream進(jìn)行數(shù)據(jù)推送

    Spring使用event-stream進(jìn)行數(shù)據(jù)推送

    這篇文章主要介紹了Spring使用event-stream進(jìn)行數(shù)據(jù)推送,前端使用EventSource方式向后臺(tái)發(fā)送請求,后端接收到之后使用event-stream方式流式返回,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-03-03
  • Spring實(shí)戰(zhàn)之緩存使用key操作示例

    Spring實(shí)戰(zhàn)之緩存使用key操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之緩存使用key操作,結(jié)合實(shí)例形式分析了Spring緩存使用key具體配置、屬性、領(lǐng)域模型等相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01
  • 分享Java常用幾種加密算法(四種)

    分享Java常用幾種加密算法(四種)

    Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細(xì)規(guī)范。本文給大家分享java常用的幾種加密算法,需要的朋友可以參考下
    2015-10-10

最新評(píng)論

博兴县| 阿荣旗| 旺苍县| 沁源县| 上饶市| 黔东| 安国市| 恩平市| 西乌| 东山县| 珲春市| 黄平县| 开平市| 平乡县| 顺昌县| 基隆市| 滦南县| 托克托县| 阳江市| 壤塘县| 巧家县| 库车县| 永胜县| 吕梁市| 昭觉县| 乌鲁木齐市| 太和县| 中西区| 东乡县| 浙江省| 亳州市| 兖州市| 石河子市| 东乡县| 厦门市| 清水河县| 阳西县| 西峡县| 泗水县| 龙海市| 彩票|