20201227のJavaに関する記事は10件です。

【Java ~真偽値~】勉強メモ2

Java学習中。
復習に見返せるようにメモしていきます。
ほぼ自分の勉強メモです。
過度な期待はしないでください。

真偽値

  • 真偽値とは

真偽値とは、「true」と「false」という2つの値がある。
trueは真(正しい)、falseは偽(間違っている)を意味する。
真偽値のデータ型はboolean型です。

  • 比較演算子

比較演算子とは、値を比較するための記号で、比較した結果は真偽値(trueかfalse)になる。
「x == y」は、xとyが同じかどうかを比較し、同じであればtrue、違っていればfalseとなる。
また「x != y」はその逆になる。

// ①「==」を用いて、値を比較した結果を出力
System.out.println(12 / 4==3);

// ②「!=」を用いて、値を比較した結果を出力
System.out.println(12 / 4!=3);

// boolean型の変数boolを定義し、「3 * 9 == 27」を代入
boolean bool = 3 * 9 == 27;

// ③変数boolの値を出力してください
System.out.println(bool);
出力結果
①true

②false

③true


  • 比較演算子/大小比較

<, >という記号は数学でも用いる大小比較の記号です。
x < yはxがyより小さければtrue, 大きければfalseを返します。x > yはその逆となる。

// 8と5を比較し、falseとなるように出力
System.out.println(8 < 5);

// 3と2を比較し、trueとなるように出力
System.out.println(3 >= 2);


  • 論理演算子

論理演算子は、「かつ」「または」「~でない」を表現する記号。

-「かつ」は、&& で表現し、「条件1 && 条件2」は「条件1がtrueかつ条件2もtrue」であれば結果もtrueになり、
どちらか一方でもfalseであれば結果はfalseになる。

System.out.println(8 < 5 && 3 >= 2);
// 出力結果 → false


-「または」は、| | で表現し、「条件1 || 条件2」は、「条件1または条件2のどちらか一方でもtrue」であれば
結果はtrueになる。

System.out.println(8 < 5 || 3 >= 2);
// 出力結果 → true


-「~でない」は、! を用いると表現できます。
例えば、!(x >= 30)は「xが30以上でない(つまり30より小さい)」ときtrueになり、「xが30以上」のときfalseになる。

System.out.println(!(8 < 5));
// 出力結果 → true


過去投稿記事

【Java~変数の定義、型変換について~】勉強メモ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

base64 画面に画像を表示させる

javaでDBに保存されている画像情報から画面(html)上に画像を表示させる方法をよく忘れるのでメモとして。

データベース情報

スクリーンショット 2020-12-27 203555.png

ファイル名:サンプル画像
ファイルパス:画像の保存されているパス
上記のテーブルのような構成

 ロジック

public imageDto getImage(String id) throws Exception {
         // DBから情報を取得する   
         List<TProductImg> imgList = imgRepository.findByid(Long.parseLong(id));
        if (!ObjectUtils.isEmpty(imgList)) {
            List<String> dispImgPath = new ArrayList<>();
            for (TProductImg e : imgList) {
                StringBuffer data = new StringBuffer();
                data.append("data:image/jpeg;base64,");
                productDto.setFilename(e.getFilename());
                // 取得した画像情報をエンコード化      
                String base64 = new String(Base64.encodeBase64(Files.readAllBytes(Paths.get(e.getFilepath()))), "ASCII");
                data.append(base64);
                dispImgPath.add(data.toString());
            }
            imageDto.setDispImgPath(dispImgPath);
        }
    }

最後にエンコード化されたdispImgPathを画面(html)で表示させる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者】Javaのデータ型

はじめに Javaのデータ型と演算子についての備忘です。 1. Javaのデータ型 基本データ型とラッパークラス、あわせて関連するメソッドについてまとめておきます。 1-1. データ型一覧 Javaで用意されている基本データ型は次のようになります。 なお、最後のStringだけはデータ型ではなく、クラスオブジェクトとなります。 基本データ型 種類 サイズ 扱える範囲 ラッパークラス byte (整数型) 1byte -128 ~ 127 Byte short 短整数型 2byte -32,768 ~ 32,767 Short int 整数型 4byte -2,147,483,648 ~ 2,147,483,647 Integer long 長整数型 8byte -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 Long float 単精度浮動小数点数型 4byte 有効桁数6桁の実数 Float double 倍精度浮動小数点数型 8byte 有効桁数14桁の実数 Double boolean 真偽型 1bit true 又は false Boolean char 文字型 2byte 1文字 Character String 文字列型 なし 最大2,147,483,647文字? - <Stringオブジェクトの最大文字数について> 最大何文字まで格納できるかは、調べてもよく分かりませんでしたが、配列数の上限とメモリの上限などに左右されるようです。 <C言語との相違点> Javaのデータ型は、ほぼ、C言語と同じような構成になっていますが、相違点もあります。 気になったところは、次のとおりです。 C言語におけるlong型は4byteだが、Javaにおけるlong型は8byteである。そのため、Javaでは18桁までの整数を扱うことができる(C言語では9桁...という認識)。 C言語にはunsigned(符号なし整数)があるが、Javaの整数型にはunsignedは用意されていない(ただし、ラッパークラスで符号なし整数も表現できる)。 1-2. ラッパークラスについて 前述の基本データ型は、値のみ(数値リテラル、文字列リテラル)を格納します。 一方、ラッパークラスは、オブジェクト(参照型)としてデータを格納するため、様々なメソッドを使用することができます。 以下、ラッパークラスの使用例として、(個人的に)よく使いそうなメソッドを挙げておきます。 1-2-1. 数値型から文字列型への変換 数値型から文字列型に変換するには、toStringメソッドを使います。 Sample01.java public class Sample01 { public static void main(String[] args) { int num = 10; String numStr = Integer.toString(num); // toStringメソッドで文字列に変換 System.out.println(num + 1); // numは数値なので加算される System.out.println(numStr + 1); // numStrは文字列なので文字列として結合される } } ターミナル $ javac Sample01.java $ java Sample01 11 101 toStringメソッドは、数値型の全てのラッパークラスで使用できます(つまり、Byte、Short、Integer、Long、Float、Doubleの6つ)。 1-2-2. 文字列型から数値型への変換 文字列型から数値型に変換するには、valueOfメソッドを使います。 Sample02.java public class Sample02 { public static void main(String[] args) { String numStr = "100"; int num = Integer.valueOf(numStr); // valueOfメソッドで文字列に変換 System.out.println(numStr + 1); // numStrは文字列なので文字列として結合される System.out.println(num + 1); // numは数値なので加算される } } ターミナル $ javac Sample02.java $ java Sample02 1001 101 1-3. Stringオブジェクトについて これは、ラッパークラスではないですが、必要性の高いものなので挙げておきます。 1-3-1. 文字列の長さを取得する Sample03.java public class Sample03 { public static void main(String[] args) { String str1 = "あいうえお"; // 日本語文字列 System.out.println(str1.length()); // 5文字 String str2 = "abcdefg"; // 英語文字列 System.out.println(str2.length()); // 7文字 } } 2. Javaの演算子 2-1. 主な演算子一覧 演算子 説明 種類 + 加算 算術演算子 - 減算 算術演算子 * 乗算 算術演算子 / 除算 算術演算子 % 剰余 算術演算子 ++ 1加算(インクリメント) 算術演算子(単項) -- 1減算(デクリメント) 算術演算子(単項) += 和の代入 代入演算子 -= 差の代入 代入演算子 *= 積の代入 代入演算子 /= 商の代入 代入演算子 & ビットAND ビット演算子 | ビットOR ビット演算子 ^ ビットXOR ビット演算子 ~ ビットNOT ビット演算子(単項) << ビット左シフト ビット演算子 >> ビット右シフト ビット演算子 2-2. ビット演算子の使い方 Bitop.java public class Bitop { public static void main(String[] args) { int n1 = 4; // 2進数 0100 int n2 = 5; // 2進数 0101 int n; n = n1 & n2; // 0100 and 0101 = 0100 System.out.println(n); // 4を出力 n = n1 | n2; // 0100 or 0101 = 0101 System.out.println(n); // 5を出力 n = n1 ^ n2; // 0100 xor 0101 = 0001 System.out.println(n); // 1を出力 n = ~n1; // ~0100 = 1011 System.out.println(n); // -5を出力(0100 の 2の補数) n = n1 << 1; // 0100 を左に1ずらす = 1000 System.out.println(n); // 8を出力 n = n1 >> 2; // 0100 を右に2ずらす = 0001 System.out.println(n); // 1を出力 } } メモ 個人的な備忘として限定公開にしていましたが、参照するのが面倒なので全体に公開とさせていただきました。 限定公開にした理由が思い出せないのですが、おそらく半端な記述があるように思います。 何か間違いなどあればご指摘をいただけると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring × Gradleにおいて[jpa-schema-gradle-plugin]プラグインを用いてDDLを自動生成する

概要・背景

SpringBootのJavaアプリにおいて、application.propertiesにspring.jpa.hibernate.ddl-auto=create-dropとかDDLに関する設定値を定義すればテーブルを自動生成してくれるけど、
「毎回dropされてデータが初期化されてしまう」とか「移行用とかなんだかんだでDDL必要だよね」っていうシーンでは融通が利かないので、DDLを自動生成するgradleタスクを作成した。

良さげなプラグインjpa-schema-gradle-pluginが公開されていたのでこれを利用する。
このプラグインは指定パッケージ配下(packageToScanの設定値)の中でEntityクラスのものを読み込んでDDLを作成してくれる。

前提条件

Spring Boot
gradle
(build.gradleの使い方とかは理解しているものとする。)

準備

1. プラグイン呼び出しのアプリ設定

jpa-schema-gradle-pluginのHow to Useに従い、必要な設定値を定義していく。
今回自分はDBはOracle、OR mapperはHibernateなので、最終的な最終的な設定値は以下のようになった。

build.gradle
plugins {
  id 'io.github.divinespear.jpa-schema-generate' version '0.3.6'
}
dependencies {
  implementation 'com.oracle.database.jdbc:ojdbc8:19.8.0.0'
}
generateSchema {
    vendor = 'hibernate'
    packageToScan = ['com.example.domain']   //自身のgradleプロジェクト または domainのディレクトリを直指定する。
    databaseProductName = 'Oracle12'
    scriptAction = 'drop-and-create'   //drop.sqlとcreate.sqlが作成される。
    properties = [
            'hibernate.dialect': 'org.hibernate.dialect.Oracle12cDialect',
            'hibernate.physical_naming_strategy': 'org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy',    //column nameで"_"が入るようにする。
            'hibernate.implicit_naming_strategy': 'org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy'
    ]
}

2.Entityの用意
Entityは以下の用にsrc/main/java/com/example/domain/にCustomer.javaとSpringUser.javaを用意した。

Customer.java
package com.example.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "CUSTOMER")
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_CUSTOMER_GENERATOR")
    @SequenceGenerator(name = "SEQ_CUSTOMER_GENERATOR", sequenceName = "SEQ_CUSTOMER", allocationSize = 1)
    private Integer id;
    @Column
    private String firstName;
    @Column
    private String lastName;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(nullable = true, name = "USER_NAME")
    private SpringUser user;

}
SpringUser.java
package com.example.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;

import javax.persistence.*;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "SPRING_USER")
@ToString(exclude = "customers")    //これはフィールド変数のcustomers
public class SpringUser {
    @Id
    private String userName;
    @JsonIgnore
    private String encodedPassword;
    @JsonIgnore
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
    private List<Customer> customers;
}

実行

上述のbuild.gradleを作ったら、"Refresh all Gradle Projects"を忘れずに実行する(gradleタスクが追加される)。
ターミナルからgradle generateSchemaと実行してやれば、build/generated-schema/create.sqlが作成される(デフォルトの出力先)。

出来上がったcreate.sqlがこちら。
Customer.javaで定義した通り、SEQUENCEもきちんと反映して作成されている。
カラムの物理名に"_"をいれるかどうかなどは、build.gradleで設定した値"SpringPhysicalNamingStrategy"で変更したりできるので、細かい仕様は、jpa-schema-gradle-pluginのHow to Useを読めばいいと思います。

create.sql
create sequence seq_customer start with 1 increment by  1;
create table customer (id number(10,0) not null, first_name varchar2(255 char), last_name varchar2(255 char), user_name varchar2(255 char), primary key (id));
create table spring_user (user_name varchar2(255 char) not null, encoded_password varchar2(255 char), primary key (user_name));
alter table customer add constraint FKc7gvbu1i8l83wyt8q39egdfka foreign key (user_name) references spring_user;

陥ったトラブル

トラブル1: KotlinNullPointerException
jpa-schema-gradle-pluginのHow to Useを見ると、
persistence.xmlを使用しない場合の最低限の設定値は、
vendor = 'hibernate'
packageToScan = ['com.example.domain']
だけのように見えるがこれだと、generateSchemaを実行したときにKotlinNullPointerExceptionが発生する。
⇒解決方法: databaseProductNameを設定する必要がある。

トラブル2: gradleタスクにgenerateSchemaは登録されるが、実行してもcreate.sqlが作成されない
イージーミスでした。scriptAction = 'drop-and-create'が抜けているだけでした。

まとめ

DDLを自動生成することで、プロジェクト参画メンバーの環境構築を円滑に行うことができるため、このプラグインの導入はおすすめです。
まぁ最近ではflywayとか使ってDDLの自動生成や移行の簡略化とかも簡単にできますが、一度自分でプラグインを作ってみたり、追うことで新しい技術を取り込むときのハードルを下げることができると思っています。

ここまで読んでいただきありがとうございました。:bow:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java認定資格】 SE 11 Silver合格体験記(2020/12/26)

合格しました!

昨日JavaSilverの認定試験を受験し、無事合格しました!
思ったより難しく、受けているときは落ちたと思っていました笑

私自身いろいろなサイトにお世話になったので、僭越ながら合格体験記として、勉強法申し込み方法当日の心構えなどを紹介します。

筆者のバックグラウンド

文系大学出身の20卒です。都内のIT企業で働いています。

◆業務経歴
 4月    主にPython初級レベルの新人研修を受ける
 5月    部署でJava研修(という名の自習)を受ける
 6月~現在 環境移行・オープン化案件でテストや運用監視業務を担当

Javaに初めて触れたのは2020年5月です。
業務でもたまーにJavaのエラー調査等やらせてもらったことはありましたが、Javaの知識はほぼ独学で身につけました。

勉強法

①Java初心者時代

5月に勉強を始めたころは、Javaのことを何も知らず、
新人研修で学んだPythonの単純さとの違いに混乱しました。

とりあえず先輩おすすめのスッキリわかるJava入門 第3版で勉強を始めました。

この本をはじめとする「スッキリシリーズ」はプログラムの書き方だけでなく、初心者にもわかりやすい例えを用いてその仕組みまで教えてくれるので本当に良書です。

6月末に1冊終わらせた頃には、JavaSilverの勉強を本格的に始めるのに十分な知識を身につけることができたと思います。

②資格勉強開始

本格的に勉強を始めたのは11月半ばです。
使った教材は、徹底攻略Java SE 11 Slver問題集、いわゆる「黒本」です。

この本は分野ごとの問題×11章+模擬試験×2回分の構成です。
問題のレベルこそ少し難しめですが、説明が丁寧で初級者にもわかりやすい内容になっています。
私は分野ごとの問題を4周(3周目以降は間違った問題のみ)、模擬試験を1回ずつ解きました。

「スッキリわかるJava」レベルの知識があれば、「黒本」1冊で十分です。
そして本番の試験問題では、なぜか15問に1問くらい模擬試験と全く同じ問題が出ます笑

ただし注意が必要なのは、誤植の多さです。
サイトの「お詫びと訂正」に訂正内容がずらっと並んでいます。問題の正誤に関わる誤植もあるので、都度都度確認が必要です。

参考までに模擬試験の点数をお教えすると、

1回目:56%(試験2週間前)
2回目:69%(試験1週間前)

という結果でした。本番は63%合格です。

1回目の点数でかなりショックを受け、1週間で模擬試験の間違えたところを徹底的に確認しました。
黒本を何周もした後で解いた模擬試験でしたが、知識の抜け漏れだらけでした。
ペーパーテストといえど、やっぱりちゃんとコードを書いて動きを確認しなきゃダメですね…

2回目の模擬試験は何とか合格点に達し、本番では81%取れました。

ちなみに最後の一週間は、偶然見つけたテックプロジンさんの問題にお世話になりました。
1つ5問でスキマ時間に学習でき、分野も大体カバーできているので、最後の確認にはもってこいでした。

申し込み方法

いろいろと登録が多くて面倒です。
手順としては以下の通りです。

  1. Oracleのアカウントを作る
  2. Oracleアカウントで、認定試験の申し込みや結果管理を行うポータルサイトCertViewにログイン
  3. CertViewから試験運営会社であるピアソンVUEのサイトに移動・試験日程を選択して申し込み

いちおうピアソンVUEのサイトに手順が載っていますが、わかりづらいので以上の手順に従って登録していくイメージを持っておくと良いと思います。

当日の心構え

私は地元のテストセンターで受験しました。
受験会場に行く前に知っておいたほうが良いことをいくつか紹介します。

①身分証明書は2種類必要

有効な身分証明書を確認し、必ず2種類持っていきましょう。

②試験会場では勉強不可

早めに到着することは大事ですが、会場に入ってしまうともう勉強できません。
私は30分前に会場付近に到着し、近くの公園で最終確認をしてから入場しました。

③証明書に掲載される写真撮影がある

メイクはちゃんとしていきましょう。
私はちゃんとメイクをしていきましたが、ブサイクな写真になってしまいました。

おわりに

現時点で伝えたいことはこれくらいです。
また何か思い出したら追記します。
追加で何かあればコメントお願いします!

最後まで読んでくださってありがとうございました^^

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java認定資格】取れたてホヤホヤ! SE 11 Silver合格体験記(2020/12/26)

合格しました!

昨日JavaSilverの認定試験を受験し、無事合格しました!
思ったより難しく、受けているときは落ちたと思っていました笑

私自身いろいろなサイトにお世話になったので、僭越ながら合格体験記として、勉強法申し込み方法当日の心構えなどを紹介します。

筆者のバックグラウンド

文系大学出身の20卒です。都内のIT企業で働いています。

◆業務経歴
 4月    主にPython初級レベルの新人研修を受ける
 5月    部署でJava研修(という名の自習)を受ける
 6月~現在 環境移行・オープン化案件でテストや運用監視業務を担当

Javaに初めて触れたのは2020年5月です。
業務でもたまーにJavaのエラー調査等やらせてもらったことはありましたが、Javaの知識はほぼ独学で身につけました。

勉強法

①Java初心者時代

5月に勉強を始めたころは、Javaのことを何も知らず、
新人研修で学んだPythonの単純さとの違いに混乱しました。

とりあえず先輩おすすめのスッキリわかるJava入門 第3版で勉強を始めました。

この本をはじめとする「スッキリシリーズ」はプログラムの書き方だけでなく、初心者にもわかりやすい例えを用いてその仕組みまで教えてくれるので本当に良書です。

6月末に1冊終わらせた頃には、JavaSilverの勉強を本格的に始めるのに十分な知識を身につけることができたと思います。

②資格勉強開始

本格的に勉強を始めたのは11月半ばです。
使った教材は、徹底攻略Java SE 11 Slver問題集、いわゆる「黒本」です。

この本は分野ごとの問題×11章+模擬試験×2回分の構成です。
問題のレベルこそ少し難しめですが、説明が丁寧で初級者にもわかりやすい内容になっています。
私は分野ごとの問題を4周(3周目以降は間違った問題のみ)、模擬試験を1回ずつ解きました。

「スッキリわかるJava」レベルの知識があれば、「黒本」1冊で十分です。
そして本番の試験問題では、なぜか15問に1問くらい模擬試験と全く同じ問題が出ます笑

ただし注意が必要なのは、誤植の多さです。
サイトの「お詫びと訂正」に訂正内容がずらっと並んでいます。問題の正誤に関わる誤植もあるので、都度都度確認が必要です。

参考までに模擬試験の点数をお教えすると、

1回目:56%(試験2週間前)
2回目:69%(試験1週間前)

という結果でした。本番は63%合格です。

1回目の点数でかなりショックを受け、1週間で模擬試験の間違えたところを徹底的に確認しました。
黒本を何周もした後で解いた模擬試験でしたが、知識の抜け漏れだらけでした。
ペーパーテストといえど、やっぱりちゃんとコードを書いて動きを確認しなきゃダメですね…

2回目の模擬試験は何とか合格点に達し、本番では81%取れました。

ちなみに最後の一週間は、偶然見つけたテックプロジンさんの問題にお世話になりました。
1つ5問でスキマ時間に学習でき、分野も大体カバーできているので、最後の確認にはもってこいでした。

申し込み方法

いろいろと登録が多くて面倒です。
手順としては以下の通りです。

  1. Oracleのアカウントを作る
  2. Oracleアカウントで、認定試験の申し込みや結果管理を行うポータルサイトCertViewにログイン
  3. CertViewから試験運営会社であるピアソンVUEのサイトに移動・試験日程を選択して申し込み

いちおうピアソンVUEのサイトに手順が載っていますが、わかりづらいので以上の手順に従って登録していくイメージを持っておくと良いと思います。

当日の心構え

私は地元のテストセンターで受験しました。
受験会場に行く前に知っておいたほうが良いことをいくつか紹介します。

①身分証明書は2種類必要

有効な身分証明書を確認し、必ず2種類持っていきましょう。

②試験会場では勉強不可

早めに到着することは大事ですが、会場に入ってしまうともう勉強できません。
私は30分前に会場付近に到着し、近くの公園で最終確認をしてから入場しました。

③証明書に掲載される写真撮影がある

メイクはちゃんとしていきましょう。
私はちゃんとメイクをしていきましたが、ブサイクな写真になってしまいました。

おわりに

現時点で伝えたいことはこれくらいです。
また何か思い出したら追記します。
追加で何かあればコメントお願いします!

最後まで読んでくださってありがとうございました^^

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaでGoogle Cloud Vision API 使ってみた

前提条件

・gradleのプロジェクト
・GCPのアカウントを登録していること
(アカウント登録、APIの利用、認証キー発行についてはこちらを参照してください)

ライブラリの追加

gradleのライブラリの追加はMaven Repositoryで調べるのが一番早いです。

compile group: 'com.google.cloud', name: 'google-cloud-vision', version: '1.100.9'

認証情報の設定

GCPのAPIを利用するときに認証情報が必要になります。
GCPのコンソール上から認証情報を作成し、JSONファイルをダウンロードします

ダウンロードしたJSONファイルをプロジェクトの中に入れて、実行の構成環境追加(新規)
変数にはGOOGLE_APPLICATION_CREDENTIALS
値にはJsonファイルの絶対パス.json

サンプルコードの実行

google公式サンプルのURL

sample.java
void main() {
        try {
            //読み込み画像を指定
            String inputImgPath = "絶対パス.png";

            //解析結果をテキストファイルで抽出
            //result.txtは作っておく
            PrintStream outputResultPath = new PrintStream(new FileOutputStream("絶対パス/result.txt"), true);

            detectText(inputImgPath, outputResultPath);
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
       }
}
    //サンプルコードより引用
    public static void detectText(String filePath, PrintStream out) throws Exception, IOException {
          List<AnnotateImageRequest> requests = new ArrayList<>();

          ByteString imgBytes = ByteString.readFrom(new FileInputStream(filePath));

          Image img = Image.newBuilder().setContent(imgBytes).build();
          Feature feat = Feature.newBuilder().setType(Type.TEXT_DETECTION).build();
          AnnotateImageRequest request =
              AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build();
          requests.add(request);

          try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) {
            BatchAnnotateImagesResponse response = client.batchAnnotateImages(requests);
            List<AnnotateImageResponse> responses = response.getResponsesList();

            for (AnnotateImageResponse res : responses) {
              if (res.hasError()) {
                out.printf("Error: %s\n", res.getError().getMessage());
                return;
              }

              // For full list of available annotations, see http://g.co/cloud/vision/docs
              for (EntityAnnotation annotation : res.getTextAnnotationsList()) {
                //テキストを出力
                out.printf("Text: %s\n", annotation.getDescription());
                //座標を出力(いらないなら下の文を消す)
                out.printf("Position : %s\n", annotation.getBoundingPoly());
              }
            }
          }
        }
    }

下の画像の文字列を抽出してみました。
文字列.jpg

抽出結果です。

Text: 全思董アォント
『フェルトペン】
有料版:第二水準ぎの演字(6,700文字以上)录
無料版:教育演字(1,006字) +a..? 4绿
小学一年生の手書女字を元に作成した
オリジナル漢字もりもりの日本語フォントです。

収録の文字が正確に読み取られていませんでした。しかしこのフォントを読み込めるのは中々精度が高いですね。

文字の座標を出すとこんな感じで出してくれます。

Position : vertices {
  x: 33
  y: 53
}
vertices {
  x: 451
  y: 53
}
vertices {
  x: 451
  y: 310
}
vertices {
  x: 33
  y: 310
}

Text: 全
Position : vertices {
  x: 76
  y: 58
}
vertices {
  x: 125
  y: 58
}
vertices {
  x: 125
  y: 101
}
vertices {
  x: 76
  y: 101
}
以下省略

今回はgradle利用者を対象に書いてみました。
ソースコードは理解するのに難しいですが、最初はコピペして使ってみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RxJavaの動作を理解していく

Reactiveの勉強記事

Reactiveを理解したいが何もわからんので、
Reactive Programming With RxJava のサンプルコードが、裏でどのように動いているのかを記述していく。

2016年の本なので、Observable.create のような Deprecatedとなっている古いAPIなどを使用している。

RxJava

簡単な登場人物

store-uml-RxJava.png

store-uml-RxJava_2.png

シンプル

fun main(args: Array<String>) {
    Observable.create<String> { s ->
        s.onNext("one")
        s.onCompleted()
    }.subscribe { s -> println("VALUE -> $s") }
}

store-uml-RxJava_sequence1.png

  • create {s -> s.OnNext("one") ...}
    • 引数のラムダ式は OnSubscribe の実装として解釈される。
  • subscribe { s -> println("VALUE -> $s") }
    • 引数のラムダ式は Action1 という内部的に使用されるインターフェイスの実装となる、
    • subscribe の内部で Action1 をwrapして Subscriber のインスタンスを作成
    • その後 OnSubscribecall を呼び出す。
      • これによって create の引数のラムダ式が呼び出される。
      • call の引数は直前に作成した Subscriber
    • ラムダ式は引数の Subscriber に対して、 onNext を呼び出す。
    • SubscriberonNext は、 subscribe の引数のラムダ式をcallすることで呼び出す。

doOnNext

fun main(args: Array<String>) {
    Observable.create<String> { s ->
        s.onNext("one")
        s.onCompleted()
    }.doOnNext { i -> println("doOnNext $i") }
            .subscribe { s -> println("VALUE -> $s") }
}

store-uml-RxJava_sequence2.png

オレンジが doOnNext 関連によって作成される処理
proxy的な動きをしていることがわかる

map

fun main(args: Array<String>) {
    Observable.create<String> { s ->
        s.onNext("one")
        s.onCompleted()
    }.map { s -> "hello $s" }
            .subscribe { s -> println("SOME VALUE -> $s") }
}

store-uml-RxJava_sequence3.png

doOnNext とほぼ同じ動作

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RxJavaの基本的な処理シーケンス(古め)

Reactiveの勉強記事

Reactiveを理解したいが何もわからんので、
Reactive Programming With RxJava のサンプルコードが、裏でどのように動いているのかを記述していく。

2016年の本なので、Observable.create のような Deprecatedとなっている古いAPIなどを使用している。

RxJava

簡単な登場人物

store-uml-RxJava.png

store-uml-RxJava_2.png

シンプル

fun main(args: Array<String>) {
    Observable.create<String> { s ->
        s.onNext("one")
        s.onCompleted()
    }.subscribe { s -> println("VALUE -> $s") }
}

store-uml-RxJava_sequence1.png

  • create {s -> s.OnNext("one") ...}
    • 引数のラムダ式は OnSubscribe の実装として解釈される。
  • subscribe { s -> println("VALUE -> $s") }
    • 引数のラムダ式は Action1 という内部的に使用されるインターフェイスの実装となる、
    • subscribe の内部で Action1 をwrapして Subscriber のインスタンスを作成
    • その後 OnSubscribecall を呼び出す。
      • これによって create の引数のラムダ式が呼び出される。
      • call の引数は直前に作成した Subscriber
    • ラムダ式は引数の Subscriber に対して、 onNext を呼び出す。
    • SubscriberonNext は、 subscribe の引数のラムダ式をcallすることで呼び出す。

doOnNext

fun main(args: Array<String>) {
    Observable.create<String> { s ->
        s.onNext("one")
        s.onCompleted()
    }.doOnNext { i -> println("doOnNext $i") }
            .subscribe { s -> println("VALUE -> $s") }
}

store-uml-RxJava_sequence2.png

オレンジが doOnNext 関連によって作成される処理
proxy的な動きをしていることがわかる

map

fun main(args: Array<String>) {
    Observable.create<String> { s ->
        s.onNext("one")
        s.onCompleted()
    }.map { "hello $it" }
            .subscribe { s -> println("VALUE -> $s") }
}

store-uml-RxJava_sequence3.png

doOnNext とほぼ同じ動作

別ThreadからのPublisher

fun main(args: Array<String>) {
    println(Thread.currentThread())
    Observable.create<String> { s ->
        Thread {
            println(Thread.currentThread())
            s.onNext("one")
            s.onNext("two")
            s.onCompleted()
        }.start()
    }.subscribe { s -> println("VALUE -> $s by ${Thread.currentThread()}") }
}

// 出力結果
Thread[main,5,main]
Thread[Thread-0,5,main]
VALUE -> one by Thread[Thread-0,5,main]
VALUE -> two by Thread[Thread-0,5,main]
VALUE -> three by Thread[Thread-0,5,main]

store-uml-RxJava_sequence4.png

別スレッドでpublishされた場合は、そのスレッドでsubscribeされる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】hasNext関数の使い方

プログラミング勉強日記

2020年12月27日
【Java】標準入力を取得・出力する方法で標準入力について扱っているが、そのときにhasNextの存在を知らなかったので、今日簡単にまとめる。

Scannerクラスとは

 標準出力するときやファイルのなかみを読み込むときに使う。
 Scannnerクラスのインスタンスを作る際に標準出力の場合はSystem.inをファイルを読み込む場合はfileオブジェクトを設定する。

基本的な書き方
Scanner 変数 = new Scanner();

hasNext関数とは

 Scannnerクラスでファイルを読み込んだときにまだ繰り返し処理ができるかどうか判定する処理である。前から順番に値を取得して、まだ値を取得できるときにはtrueを、これ以上値を取得できないときにはfalseを返す。
 いくつ入力されるかわからない場合は、for文で回数を指定して受け取ることができないので、そういったときに使う。

 hasNext関数とセットで使われるのがnext関数である。next関数は前から順番に値を取得していき、hasNext関数で値があるかを判定する場所を次に進める。

基本的な書き方
while(繰り返したいオブジェクト.hasNext()) {
  String 変数 = 繰り返したいオブジェクト.next();
  後続処理;
}

 

サンプルコード

ファイルの内容を読み込むプログラム
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Sample {
  public static void main(String[] args) throws FileNotFoundException {
    File file = new File("sample.txt");
    Scanner scanner = new Scanner(file);
    while (scanner.hasNext()) {
      String str = scanner.next();
      System.out.println(str);
    }

    scanner.close();
  }
}
キーボードから入力された文字を反転して表示するプログラム
import java.util.Scanner;

public class Sample {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        try {
            while (s.hasNext()) {
                String value = s.next();
                System.out.println(new StringBuilder(value).reverse());
            }
        } finally {
            s.close();
        }
    }
}

参考文献

ScannerのhasNextメソッドの使い方
JavaのScannerクラスのhasNext関数について現役エンジニアが解説【初心者向け】
キーボード入力から取得!JavaでScannerクラスを使う方法【初心者向け】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む