20210413のJavaに関する記事は7件です。

Java学習 基礎編 変数名の付け方

Java学習の備忘録になります。 内容は初心者なので基礎的な部分となります。 Javaに興味がある方やJava学習初心者の参考になれば幸いです。 変数名の規則とは? 変数名には、以下のような規則がある。 文字数制限はないが、あまり長い名前を付けると、タイプミスが起こりやすく、プログラムが読みにくくなる。 ・変数名には、半角英数字(A~Z、a~z、0~9)、_(アンダーバー)、$(ドルマーク)などの一部の記号を使える ・下記のようなJava言語自体が利用するキーワード(予約語)を変数名に使うことはできない int class = 10; // コンパイルエラー classという変数名はつけられない int int = 10; // コンパイルエラー intという変数名はつけられない ・数字は2文字目以降で使える(1文字目には使えない) int number1 = 10; // 2文字目以降で数字が使われているのでOK int 1number = 10; // コンパイルエラー 1文字目には使えない ・大文字/小文字は、別の文字として区別される // 下記は別々の変数として区別される int number = 10; int Number = 10; 変数名の慣習的なルール ・_(アンダーバー)、$(ドルマーク)などの記号は使わず、英数字のみを利用する ・用途のわかるような名前をつける ・1つの単語からなる変数名は、すべて小文字にする ・複数の単語を組み合わせるとよりわかりやすくなる。その際は、あとから付ける単語の先頭のみを大文字にして、単語の区切りをわかるようにする ・変数名の途中にスペースは使えない // ダメな例 int a = 10; // どのような用途で使われるのか、変数名を見ただけではわからない String userfirstname = "Sasaki"; // 単語の区切りがわかりにくい String user first name = "Sasaki"; // 変数名の途中にスペースが入っている おわりに そのほか、命名ルールがありましたらご教授ください。 よろしくお願い致します!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java アルゴリズム修行⑤】繰り返しを工夫する

ただ繰り返さない 色んな問題に触れていると、全く思いつかないというのは減ってきた気がしますが それでもまだまだとりあえずループしてゴリ押し出力!というのが少なくありません。。 解けた後にもっとスリムにやれないか??と思うこともあるので、今回はそんなスリム化の過程を書いてみたいと思います! 1~入力値までの数を足していく 1~入力値まで足していく間に "+" 最後に "="を入れて出力する というプログラムを考えたいと思います。 入力値が5であれば、 1+2+3+4+5=15 と表示するような流れです。 alog.java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int answer = 0; for(int i = 1; i <= n; i++) { // 最後は+を入れたくないので分岐させる if(i == n){ System.out.print(i); } else { System.out.print(i + "+"); answer += i; } } System.out.println("=" + answer); } } 一応これでも問題なく出力はできるんですが、最後の1回だけ+を入れないため、というたった1回しかないケースのためだけにif文があるので、繰り返しの度に条件判定を行うのはかなり無駄っぽいです。。 最後の数を表すi == n のときだけを特別扱いしてあげれば良さそうなので改良してみます。 alog.java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int answer = 0; for(int i = 1; i < n; i++) { //入力値 - 1 の数まで足す System.out.print(i + "+"); answer +=i; } //最後の入力値自身は別で足す System.out.println(n + "=" + (answer +=n)); } } 最後だけは別で足せばいいので、出力するときにanswer +=nで足すようにしました。 これで無駄な条件分岐はなくなり、見た目も処理そのものもかなり効率的になったと思います! 入力値文 +- を交互に出力する 表題の通りですが、3であれば +-+ 5であれば +-+-+ と表示するプログラムを考えます。 交互なので、奇数であれば - 偶数であれば + という分岐を考えれば良さそうです。 algo.java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); for(int i = 1; i <= n; i++){ //偶数であれば - を出力する if(i % 2 == 0){ System.out.print('-'); }else{ System.out.print('+'); } } } } ただ、これもfor文の中で条件分岐を行っているので処理回数が増えてしまいそうなので、条件分岐を外に出してみましょう。 algo.java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); //まずは入力値を2で割った数分だけ+-を出力する for(int i = 0; i < n / 2; i++){ System.out.print("+-"); } //奇数であれば最後に +を足す if(n % 2 != 0){ System.out.println('+'); } } } 偶数個分の+-をまずは出力してしまうために、for(int i = 0; i < n / 2; i++) としました。 その後、もし入力値が奇数であれば最後に+だけを足すことで for文とif文を分けることができましたね! 奇数と偶数は結構考え方として大事そうですね。。 *をn回表示し、 w個並んだら改行を入れる こちらも表題の通りのプログラムですが、2つの入力値があるとして、1番目をn、2番目をwとしたときに *をn回表示し、 w個並んだら改行を入れて出力するというプログラムを試してみます。 alog.java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int w = sc.nextInt(); for (int i = 1; i <= n; i++) { System.out.print('*'); // 表示する順番が改行を入れる個数の倍数であった場合は改行を入れる if(i % w == 0){ System.out.println(); } } } } 30 5 と入力されたときのことを考えてみると、 30個の*を出力するけど、5個出力する毎に改行を入れる。 ということになるので、「5,10,15,20,25,30」 というタイミングで改行を入れる必要がありそうです。 整理してみると、、 i番目に出力するとき、iがwの倍数であるときは、出力後に改行を入れる必要がある。 → iをwで割り切れるとき、出力後に改行を入れればいいということになります。 これをfor (int i = 1; i <= n; i++) で判定するとにより実現しています。。。 「forの中でifはもうナンセンスゴリラじゃない??」 という声が聞こえてきそうなので、改良してみましょう笑 java.algo import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int w = sc.nextInt(); for (int i = 0; i < n / w; i++) { System.out.println("*".repeat(w)); } int rest = n % w; if(rest != 0){ System.out.print("*".repeat(rest)); } } } 繰り返し出力をStringクラスのrepeatメソッドを使用して行い、 改行は for (int i = 0; i < n / w; i++)の n / w で繰り返す行数を決めています。 行数 = 改行込みで繰り返し出力する数(ループが必要な数)ということですね! もし割り切れない場合は、改行は必要ないけど出力が必要な回数が残っているので n % wで求めた余り分だけを再度出力することによって、繰り返し処理と条件分岐を分けることができました! 学んだこと 繰り返し文の中に条件分岐がある場合は、別々に分けられないか考えてみる。 条件分岐が必要な場面がどれくらい発生するかを考えてみる。 奇数と偶数で分けられるときは、単純化できるチャンス これまではとりあえず期待値が出ればよしとしていましたが、扱うデータの数が何千、何万となってくれば それだけ処理が重たくなってしまうので、for文とif文は分けるなど、できる限り見た目も処理方法もスマートにできないか考える癖を付けていこうと思います! 引き続き頑張っていきます!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WEBアプリケーションに画像をアップロードする機能を実装する方法

WEBアプリケーションに画像をアップロードする機能を実装する方法 Javaを利用して作成したWEBアプリケーションに画像投稿機能を実装する際の手順について記載します イメージとしては下記の図のようなイメージになります。 画像のアップロードにはHTMLのformタグとinputタグを利用します フロントエンド <form method="post" > <input type="file" name="uploadImage" /> <input type="submit" value="送信" /> </form> バックエンド側では、Fileクラスを利用して受け取ります バックエンド protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Fileクラスのインスタンス化(保存するディレクトリの指定) File uploadDir = new File("/Users/test/Documents/app/WebContent/images"); // リクエストパラメーターから画像の取得 Part fPart = request.getPart("uploadImage"); // 画像の名前を決める String fName = "testphoto"; // 保存処理の呼び出し save(fPart, new File(uploadDir, fName)); //保存処理 public void save(Part in, File out) throws IOException { BufferedInputStream br = new BufferedInputStream(in.getInputStream()); try (BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream(out))) { int len = 0; byte[] buff = new byte[1024]; while ((len = br.read(buff)) != -1) { bw.write(buff, 0, len); } } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

springframeworkのJavaMailSenderでメールを送る際の送信主に名前を付与する

たまたま、JavaのプロジェクトとKotlinのプロジェクトの両方で送信主に名前を付与して送信する処理を作成したので、備忘録として投稿します。 Java開発環境 version java 11 SpringBoot 2.1.0.RELEASE 既存のSimpleMailMessageを用いた処理の場合、InternetAddressを使用することが出来なかったので、MimeMessageを用いた処理に変更 変更前 SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("hoge@.com"); message.setTo("hoge"); message.setSubject("subject"); message.setText("body"); InternetAddressクラスを用いて、personalと形式を設定 InternetAddressクラス InternetAddress(StringSE address, StringSE personal, StringSE charset) 変更後 MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true , "UTF-8"); helper.setFrom(new InternetAddress( "hoge@.com" ,"不動産SHOPナカジツ", "UTF-8")); helper.setTo("hoge"); helper.setSubject("subject"); helper.setText("body"); Kotlinでの設定 こちらはJavaで設定した変更後の処理と同様の処理 version Kotlin 1.3.70 SpringBoot 2.3.4.RELEASE val message = javaMailSender!!.createMimeMessage() val helper = MimeMessageHelper(message, true) helper.setFrom(InternetAddress("hoge@.com", "不動産SHOPナカジツ", "utf-8")) helper.setTo("hoge") helper.setSubject("subject") helper.setText("body") 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Azure SDK for Java からの Storage への接続(認証)について

Azure SDK for Java からの Storage への接続(認証)について Azure上にシステムを構築するにあたって、よく使われるのがAzure Storageです。知らない方に説明するとザックリ以下のようなものです。 BLOB : テキスト、バイナリなどの大量のオブジェクトデータを格納 Table : スキーマレスな Key - Value ストア Queue : いわゆる FIFO を実現するためのキュー ここの本題ではないので、詳しく知りたい方は、以下のドキュメントを当たってください Blob (オブジェクト) Storage の概要 - Azure Storage | Microsoft Docs Table Storage の概要 - Azure のオブジェクト ストレージ | Microsoft Docs Azure Queue Storage の概要 - Azure Storage | Microsoft Docs ここでは、Azure Storage SDK を使う前段階の認証について検証をかねて解説したいと思います。他のAzureリソースを使う場合も、同じ認証方法をサポートしているので、ここで説明したような方法が使えると思います。 接続文字列 サンプルなどで一般的に扱われるのが、接続文字列によるStorageへの接続です。ポータルの、アクセスキー画面から取得できます。 以下のような形式で、プロトコル、アカウント名、アカウントキー、エンドポイントのサフィックスが定義されています。現在のAzureは、リージョンによって core.windows.net を持たない物もあるため、このようにサフィックスを定義することになってます。 DefaultEndpointsProtocol=https;AccountName=qiitaazure;AccountKey=xxxxxxxxxx;EndpointSuffix=core.windows.net SDKでは、以下のように BlobServiceClientBuilder#connectionString() に 接続文字列を渡してビルドします。 BlobServiceClient blobServiceClient = new BlobServiceClientBuilder() .connectionString(connectionString) .buildClient(); 接続文字列をどのように管理するかはここではあまり言及しませんが、マネージドIDを使えば、接続文字列を管理する必要もなくなりますから、開発とか極小規模なアプリ向けでしょうか。KeyVault に格納という話もなくはないのでしょうが、それくらいならマネージドID使いましょう。 StorageSharedKeyCredential 接続文字列とあまり違わないのですが、共有キーで認証する方法です。StorageSharedCredential を使います。実装を見ると接続文字列も内部的にはStorageSharedKeyCredentialを使っています。 StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, accountKey); BlobServiceClient blobServiceClient = new BlobServiceClientBuilder() .endpoint(String.format("https://%s.blob.core.windows.net", accountName)) .credential(credential) .buildClient(); TokenCredential インタフェースを使う BlobServiceClientBuilder には、 public BlobServiceClientBuilder credential(TokenCredential credential) が定義されており、 TokenCredential をインタフェースを実装した様々な認証方式を取ることが出来ます。 リファレンス的には以下を参照すると、色々な具象クラスが定義されいますので、少しかいつまんで説明します。 Overview (Azure SDK for Java Reference Documentation) 開発環境下での Credential 開発環境下用に、 IntelliJCredential VisualStudioCodeCredential AzureCliCredential と言った物があります。特定のIDE環境下で認証済の情報を利用してくれるので、開発環境下で使うことができます。例えば、AzureCliCredential は、 Azure CLI いわゆる az コマンドでの認証に対応します。az login でサブスクリプションに接続すると、その認証情報は ~/.azure に格納されるのですがそれを勝手に使ってくれます。 内部的には az account get-access-token --output json --resource https://storage.azure.com なコマンドを発行してStorageへのアクセスに必要なトークンを取得しています。 コード的には以下です。 AzureCliCredential azureCliCredential = new AzureCliCredentialBuilder().build(); ManagedIdentityCredential ManagedIdentityCredential はマネージドIDを有効にしたWebAppやVMなどで利用できる認証方法です。アカウントキーでの認証が不要になります。 マネージドID全般の話は以下を参照してください。SDKからの利用については、ほぼポータルでの設定話になってしまうので、割愛します。 Azure リソースのマネージド ID | Microsoft Docs ManagedIdentityCredential managedIdentityCredential = new ManagedIdentityCredentialBuilder().build(); 最終的には、DefaultAzureCredential を使えば無問題 長々と説明してきましたが、TokenCredential を実装したクラスは説明した以外にもいくつかあります。そして、それらの認証方式を全て試してくれるのが DefaultAzureCredential です。いちいちいままで紹介した個別のクラスを使う必要はありませんし、ぶっちゃけ、この DefaultAzureCredential だけ知っていれば良いレベルなのですが、実際の振る舞いは理解しておいて損は無いと思います(はまるので)。 リファレンスやDocsを見ると説明が書いてあります。 https://azuresdkdocs.blob.core.windows.net/$web/java/azure-identity/1.2.5/com/azure/identity/DefaultAzureCredential.html Azure でホストされる Java アプリケーションを認証する | Microsoft Docs コード的には以下の通りです。 DefaultAzureCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build(); JavaDocから抜粋すると、以下の順番で認証を試していってくれます。最終的にどの方法でも認証できないと、失敗となります。 EnvironmentCredential ManagedIdentityCredential SharedTokenCacheCredential IntelliJCredential VisualStudioCodeCredential AzureCliCredential 個別の動きについては、リファレンスなりDocsを当たれば良いでしょう。ソースを追いかけるのも面白うと思います。 まとめ DefaultAzureCredential を使っとけばOKということです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTTPURLConnectionでBasic認証を行う際の実装例

private void basicAuthFunction() throws IOException, ParseException { HttpURLConnection connection = null; try { final URL url = new URL(config.getRequestUrl()); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Authorization", "Basic " + config.getEncodeAuthorization()); connection.connect(); streamFunction(connection); } finally { if (connection != null) { connection.disconnect(); } } } private void streamFunction(HttpURLConnection connection) throws IOException, ParseException { try (final InputStream stream = connection.getInputStream(); final BufferedReader reader = new BufferedReader( new InputStreamReader(stream, StandardCharsets.UTF_8))) { final StringBuilder builder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { builder.append(line); } final JSONObject obj = (JSONObject) new JSONParser().parse(builder.toString()); final JSONObject data = (JSONObject) obj.get("data"); } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaでボゴソートを作ってみた

ボゴソートの概要 ソートアルゴリズムの一つ 配列内の要素を、シャッフルして昇順か降順で並び続けるまでひたすら繰り返す 完了するまでかかる時間は非常に長く、最悪無限になる可能性もある。 実用性は無く、遊びのネタ 手順 整数型のListを用いて、ソートを行う 昇順に並ぶまで、シャッフルを行う 昇順に並んだら、終了 開発環境 Windows 10 OpenJDK 15.0.2 ソースコード BogoSort.java import java.util.Arrays; import java.util.Collections; import java.util.List; public class BogoSort { public static void main(String[] args){ //初期化 List<Integer> list = Arrays.asList(5,1,2,3,4); //trueが返されるまで、ひたすら繰り返す while(isAscendingOrder(list)==false){ // シャッフルを行うメソッド Collections.shuffle(list); // 途中経過が見れる System.out.println(list); } } //List内の要素の並びが昇順ならば、trueを返す public static boolean isAscendingOrder(List<Integer> list){ int i=0; for(;i<=list.size()-2 && list.get(i)<=list.get(i+1);i++); if(i==list.size()-1){ return true; } return false; } } 動かしてみる 時間を計測して、どのくらい時間がかかるかを測定してみる まず、ソースコードを次のように変更 public static void main(String[] args){ long startTime = System.currentTimeMillis(); List<Integer> list = Arrays.asList(5,1,2,3,4); while(isAscendingOrder(list)==false){ Collections.shuffle(list); //System.out.println(list); } System.out.println(list); long endTime = System.currentTimeMillis(); System.out.println("処理時間:"+(endTime-startTime)+"ms"); } listに代入する要素の内容、個数別に計測する 昇順になったlistの内容と、処理時間を表示する スペックは割愛 結果 要素数5個の場合(内容:5,1,2,3,4) [1, 2, 3, 4, 5] 処理時間:2ms 10回実行したが、0~2ミリ秒で終わった 要素数6個の場合(内容:6,1,2,3,4,5) [1, 2, 3, 4, 5, 6] 処理時間:2ms 1~6ミリ秒で終わる 要素数10個の場合(内容:10,1,2,3,4,5,6,7,8,9) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 処理時間:856ms 最小2ミリ、最大で約3000ミリ秒もかかった 要素数11個の場合(内容:11,1,2,3,4,・・・10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 処理時間:10161ms 3回試行した結果が、5000ミリ秒台が2回、10000ミリ秒台が1回だった 感想 ボゴソートがどのくらい効率が悪いのかが体感できました。 15個以上はいつ終わるか分からなかったので測定できませんでしたが、非常に面白かったです。 参考にしたサイト - 追記(2021/4/13) 載せ忘れてたので、追記しました。 ボゴソート - Wikipedia Java - 配列をシャッフルする - 覚えたら書く
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む