Python dictionary → Java Map

Python dictionary を 標準出力してJavaでMap として読み込む。

先日書いたものの勢いにまかせて、、、

Python 標準出力→Java受け取り - Oboe吹きプログラマの黙示録

Javaからプロセス起動で実行するPython と文字列の受け渡し - Oboe吹きプログラマの黙示録

では、リストではなく、Pythonの dictionary を 標準出力してJavaでMap として読み込む。というのも、
Base64 エンコードで受け渡せば安定して実行できる、

先日書いた標準 IOをまとめた Python コードに、辞書をBase64エンコードして標準出力するメソッドを
追加する。

util ディレクトリに置く stdio.py

# -*- coding: UTF-8 -*-
from base64 import b64encode
class StdIO:
    # 標準入力
    # escape=True  : inputした文字をUnicode文字列に変換してリストにする
    #                標準入力=Unicode入力を想定(Javaプロセス標準出力から受信する場合はTrueにする)
    # escape=False : inputした文字を変換なしでリストにする。
    #                標準入力=通常
    def input(self, escape=True):
        inlist = []
        try:
            if escape:
                while True:
                    inp = input('')
                    if inp == '': break
                    inlist.append(inp.encode().decode('unicode-escape'))
            else:
                while True:
                    inp = input('')
                    if inp == '': break
                    inlist.append(inp)
        except EOFError:
            pass
        return inlist
    # リストを標準出力
    #   escape=True  : リスト要素をunicode-escape にエンコードして出力
    #   code : 出力する文字コード、デフォルト 'utf-8'  ユニコード指定は、'unicode-escape'
    def printList(self, list, base64=False, code='utf-8'):
        outlist = []
        if base64==True:
            for e in list:
                data = e.encode(code)
                outlist.append(b64encode(data).decode())
        else:
            for e in list:
                data = e.encode(code)
                outlist.append(data)
        print(outlist)
    # 辞書をBase64エンコードして標準出力
    def printDictionary(self, dict):
        o = {}
        for k, v in dict.items():
            o[b64encode(("%s" % k).encode('utf-8')).decode()] = b64encode(("%s" % v).encode('utf-8')).decode()
        print(o)

Javaからプロセス起動する Python
testdictout.py

# -*- coding: UTF-8 -*-
from util.stdio import StdIO

dict = { 'a':'A', 'b':'B', 10:100 , "A":"あ" }

stdio = StdIO()
stdio.printDictionary(dict)

Java のコード

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.yipuran.function.ThrowableConsumer;
import org.yipuran.util.process.ScriptExecutor;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
try(ByteArrayOutputStream out = new ByteArrayOutputStream()){
   ScriptExecutor.runStream(()->"python script/testdictout.py"
   , ThrowableConsumer.of(i->i.transferTo(out))
   , (t, e)->{
      System.out.println("stderr : " + t );
      e.printStackTrace();
   });
   String response = out.toString();

   System.out.println(response);
   // 解析

   System.out.println("====== Google gson による解析 =========");

   Map<String, String> getmap = new GsonBuilder().serializeNulls()
   .create().fromJson(response,  new TypeToken<Map<String, String>>(){}.getType());
   
   Map<String, String> map = getmap.entrySet().stream()
   .collect(()->new HashMap<String, String>()
         , (r, t)->r.put(new String(Base64.getDecoder().decode(t.getKey()), StandardCharsets.UTF_8)
                        , new String(Base64.getDecoder().decode(t.getValue()), StandardCharsets.UTF_8))
         , (r, u)->r.putAll(u));

   map.entrySet().stream().forEach(e->{
      System.out.println(e.getKey() + " : " + e.getValue());
   });

}catch(IOException ex){
   ex.printStackTrace();
}finally{
}

結果、、、、

{'YQ==': 'QQ==', 'Yg==': 'Qg==', 'MTA=': 'MTAw', 'QQ==': '44GC'}

====== Google gson による解析 =========
a : A
A : あ
b : B
10 : 100

でも、こんなことするのは、
大量のデータには効率悪いだろうな。。