グラフィカルモデルの勉強をしていたら、集合族という聞きなれない言葉に遭遇したので調べてみた。
集合族とは、集合のあつまりのこと。
特に、ある集合Sの部分集合族とは、Sの部分集合のあつまりのことである。
具体的な例を考えてみる。
集合SをS = {1,2,3,4}と定義する。
以下にSの部分集合族をいくつか列挙してみる。
Sのべき集合は、Sの部分集合族である。
べき集合とは、以下のようにSの考えられる部分集合をすべて列挙したものである。
{{}, {1}, {2}, {3}, {4}, {1,2}, {1,3}, {1,4}, {2,3}, {2,4}, {3,4}, {1,2,3}, {1,3,4}, {1,2,4}, {2,3,4}, {1,2,3,4}}
Sのk-元部分集合からなる集合は、Sの部分集合族である。
k-元部分集合とは要素数がkの部分集合のこと。
例えば以下のようなSの1-元部分集合は、Sの部分集合族である。
{{1}, {2}, {3}, {4}}
適当にSから部分集合を選んでそれを要素とする集合を作ると、それはSの部分集合族である。
例えば、{{1,2}, {1,2,3}, {3,4}, {4}}など。
Search on the blog
2016年11月6日日曜日
2016年11月3日木曜日
デフォルト文字コードを変えてavroのserialize結果を確認した
ちょっと気になったので実験してみた。
Javaでは、Charset.defaultCharset().name()とやると、JVMのデフォルトの文字コードを取得できる。この文字コードはOSのロケールや文字コードに依存して決まるらしい。
EclipseだとProject-Propertiesから文字コードを変更できるので、このへんをいろいろ変えてどうなるか見てみた。
実験コード
結果
Javaでは、Charset.defaultCharset().name()とやると、JVMのデフォルトの文字コードを取得できる。この文字コードはOSのロケールや文字コードに依存して決まるらしい。
EclipseだとProject-Propertiesから文字コードを変更できるので、このへんをいろいろ変えてどうなるか見てみた。
実験コード
package com.kenjih.sample; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.Charset; import org.apache.avro.Schema; import org.apache.avro.SchemaBuilder; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.generic.GenericRecord; import org.apache.avro.io.DatumWriter; import org.apache.avro.io.EncoderFactory; import org.apache.avro.io.JsonEncoder; public class Main { public void run() throws IOException { // set default encoding System.out.println("default encoding=" + Charset.defaultCharset().name()); // create avro record Schema schema = SchemaBuilder.record("test").namespace("hoge.fuga") .fields() .name("keyword").type().stringType().noDefault().endRecord(); String keyword = "あいうえお"; GenericRecord record = new GenericData.Record(schema); record.put("keyword", keyword); // serialize with json encoder DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema); ByteArrayOutputStream out = new ByteArrayOutputStream(); JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, out); writer.write(record, encoder); encoder.flush(); // see bytes of keyword byte[] bytes = keyword.getBytes(); for (int i = 0; i < bytes.length; i++) { System.out.print(bytes[i] + ","); } System.out.println(); // see bytes of serialize message bytes = out.toByteArray(); for (int i = 0; i < bytes.length; i++) { System.out.print(bytes[i] + ","); } System.out.println(); // bytes are encoded with UTF-8 System.out.println(out.toString("UTF-8")); } public static void main(String[] args) throws IOException { new Main().run(); } }
結果
以下のようにavroのserializerは、JVMのデフォルト文字コードが何であれ、UTF-8エンコーディングで結果を返すらしい。ということでシリアライズ結果を文字列に格納したい場合は、toString("UTF-8")しておけばOKっぽい。
UTF-8のとき
UTF-16のとき
Shift_jisのとき
UTF-8のとき
default encoding=UTF-8
-29,-127,-126,-29,-127,-124,-29,-127,-122,-29,-127,-120,-29,-127,-118,
123,34,107,101,121,119,111,114,100,34,58,34,-29,-127,-126,-29,-127,-124,-29,-127,-122,-29,-127,-120,-29,-127,-118,34,125,
{"keyword":"あいうえお"}
UTF-16のとき
default encoding=UTF-16
-2,-1,48,66,48,68,48,70,48,72,48,74,
123,34,107,101,121,119,111,114,100,34,58,34,-29,-127,-126,-29,-127,-124,-29,-127,-122,-29,-127,-120,-29,-127,-118,34,125,
{"keyword":"あいうえお"}
Shift_jisのとき
default encoding=Shift_JIS
-126,-96,-126,-94,-126,-92,-126,-90,-126,-88,
123,34,107,101,121,119,111,114,100,34,58,34,-29,-127,-126,-29,-127,-124,-29,-127,-122,-29,-127,-120,-29,-127,-118,34,125,
{"keyword":"あいうえお"}
SLF4Jでロギング
SLF4Jとは?
Simple Logging Facade for Java。ロギングフレームワークのFacade的なやつ。
SLF4Jを使うことで、特定のロギングフレームワークの実装に依存することなく、ロギング処理が書ける。
準備
gradleでプロジェクトを作成すると、
デフォルトでslf4j-apiがdependenciesに入ってた。
使ってみる
このままで実行するとエラーになる。
ここで注目すべきは、コード自体はコンパイルできること。
エラー内容は実行するときにロガー実装が見つかりませんでした的な内容。つまり特定のロガー実装に依存することなくロギングコードが書けて、このソースの使用者が使用するロガーを決めることができるということ。これはライブラリを書くときに非常に便利。なぜなら特定のロガー実装をエンドユーザーに強制する必要がなくなるから。
ということで以下ロガー実装との組み合わせを試していく。
log4j2を使う
ロガー実装としてlog4j2を使うことにする。
build.gradleに以下のdependencyを追記。
クラスパスに以下のファイルをlog4j2.xmlという名前で置く。
実行。
log4jを使う
log4j 1系でやってみる。
依存ライブラリは以下のものを使う。
設定ファイルは、log4j.xmlという名前でクラスパスに置く。
実行。
Simple Logging Facade for Java。ロギングフレームワークのFacade的なやつ。
SLF4Jを使うことで、特定のロギングフレームワークの実装に依存することなく、ロギング処理が書ける。
準備
gradleでプロジェクトを作成すると、
gradle init --type java-library
デフォルトでslf4j-apiがdependenciesに入ってた。
dependencies { compile 'org.slf4j:slf4j-api:1.7.13' testCompile 'junit:junit:4.12' }
使ってみる
package com.kenjih.logging; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Sample { public void run() { Logger logger = LoggerFactory.getLogger(Sample.class); logger.info("Hello, world!"); } public static void main(String[] args) { new Sample().run(); } }
このままで実行するとエラーになる。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
ここで注目すべきは、コード自体はコンパイルできること。
エラー内容は実行するときにロガー実装が見つかりませんでした的な内容。つまり特定のロガー実装に依存することなくロギングコードが書けて、このソースの使用者が使用するロガーを決めることができるということ。これはライブラリを書くときに非常に便利。なぜなら特定のロガー実装をエンドユーザーに強制する必要がなくなるから。
ということで以下ロガー実装との組み合わせを試していく。
log4j2を使う
ロガー実装としてlog4j2を使うことにする。
build.gradleに以下のdependencyを追記。
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.7' compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.7' compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.7'
クラスパスに以下のファイルをlog4j2.xmlという名前で置く。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy/MM/dd HH:mm:ss} %-5level - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
実行。
2016/11/03 19:40:51 INFO - Hello, world!
log4jを使う
log4j 1系でやってみる。
依存ライブラリは以下のものを使う。
compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.13' compile group: 'log4j', name: 'log4j', version: '1.2.17'
設定ファイルは、log4j.xmlという名前でクラスパスに置く。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" > <appender name="stdout" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%m%n" /> </layout> </appender> <root> <appender-ref ref="stdout"/> </root> </log4j:configuration>
実行。
Hello, world!
登録:
投稿 (Atom)