20210417のJavaに関する記事は12件です。

継承の関係が民法典のパンデクテン方式に似てるなという感想

はじめに 私は昨年から法学部生として法律を勉強しています。 民法講義の一回目で学ぶパンデクテン方式が、プログラミングの継承の考え方に似てるなと思ったのでまとめてみます。 民法典でパンデクテン方式をとる意義 日本には民法という法律があります。 これは買い物や結婚など、私たちの生活に密接に関わるもののルールを定めています。 生活の中には様々な法律関係があるため、民法の条文数は1000を超えています。(第1条、第2条というやつです。) 民法典ではこの大量の条文をただ並べるのではなく、必要なものを素早く見つけるために、パンデクテン方式という考え方で条文が整理されています。 パンデクテン方式とは Wikipediaでは次のように説明されています。 パンデクテン方式(パンデクテンほうしき)とは、民法典において、一般的・抽象的規定を個別的規定に先立ち「総則」としてまとめることにより、法典を体系的に編纂することに主眼をおいた著述形式である。 つまり細かい規定を定める前に、そのすべてに共通する事項をくくりだして先に提示しておくということです。 例えば買い物や結婚などについて詳しく定める前に、これらの法律行為は信義に従って誠実に行いましょうね、ということを総則に置いています。 パンデクテン方式を継承で このパンデクテン方式が下記のようなスーパークラスとサブクラスの関係で表せるのではないかと思いました。(4編と5編は省略) pande.java public class 第1編総則{ } public class 第2編物権 extends 第1編総則{ } public class 第3編債権 extends 第1編総則{ } また第2編物権や第3編債権もそれぞれ固有の総則をもっており、その編で共通の事項をくくりだしています。 まとめ 共通する部分をまとめてくくりだすることで、全体がコンパクトになり機能の所在が分かりやすくなりますね。 たまたま継承がパンデクテン方式に似てるなと思いましたが、くくりだしの考え方を用いるものは他分野でも多く見られるのではないでしょうか。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】Optionalが処理できないならデフォルト値を返そう

概要 Optionalはnullである可能性を明示的に返してくれる便利なコンテナ・オブジェクトです。 if(obj == null)... といったことをしなくてよくなったのは素晴らしいことだと思っています。 考察内容 nullをOptional型で返してSyetem.out.printすると「Optional.empty」が表示されます。 null安全なのは良いけど、WebアプリケーションのView等に表示するわけにはいかないなぁと感じたのがきっかけです。 対応方法として、Optionalを返すのではなく、nullをデフォルト値等に変換してから返してしまえばいいのではないかというのが考えです。 実装例 商品情報を持つItemオブジェクト(WebアプリケーションだとEntity想定) name、amountは必須項目なので値は必ず保持しており、descriptionはnullである可能性がある状況を想定。 descriptionはフィールドとしてはnullを保持するが、アクセサで返す値はデフォルト値として空文字にする。 これにより、Entityとしてはnullを持つのでDB値と整合性が取れ、利用側のクラス(ここではMain)はデフォルト値(空文字)を扱うことができる。 Item.java import java.util.Optional; public class Item { private String name; // DBで必須項目 private Integer amount; // DBで必須項目 private String description; // DBで任意項目(NULLの可能性がある) public Item(String name, Integer amount, String description) { this.name = name; this.amount = amount; this.description = defaltStrValue(description); } public String name() { return name; } public Integer amount() { return amount; } public String description() { return Optional.ofNullable(description).orElse(""); } public String text() { return "["+ String.format( "name: %s, amount: %d, description: %s", name, amount, description) + "]"; } } Main.java public class Main { public static void main(String...strings) { // nullをOptionalで返すと、「Optional.empty」が表示される。 System.out.println(Optional.ofNullable(null)); Item tv = new Item("BRAVIA", 79000, null); System.out.println(tv.text()); System.out.println("description is " + tv.description()); } } Optional.empty [name: BRAVIA, amount: 79000, description: null] description is Webアプリケーションなんかで、modelにそのままentityを渡して表示させると、「Optional.empty」が出てしまうので、アクセサ(Getter)でデフォルト値にしてしまうのが、適切かなぁと思った次第です。 まとめ Optionalはnull安全にできる便利なコンテナ・オブジェクトである。 利用側で処理せず、「Optional.empty」となってしまうようであれば、デフォルト値を返してしまうのがよさそう。 フィールドで保持する値(null)とアクセサで返す値(空文字)を分けることで、DB値と利用側で表示する値を区別して扱うことも可能になる。 参考 Qiita - Optionalの正しい使い方 Qiita - 【Java】Optionalの正しい使い方を学ぶ Qiita - Java 8 "Optional" ~ これからのnullとの付き合い方 ~ Qiita - [Java8] Optionalで脱Exception!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[KPI] javaで簡易todoリストを作成する

簡単な流れ 1、テーブル作成 2、サーブレット作成 3、jsp作成 テーブル作成 用途は、name(タスク)を一覧表示、登録・更新・削除を行う。 id : オートインクリメントするように。 name : 30文字までは可能。 created,updated: タイムスタンプで、デフォルトで現在日時が入るように。 create table todos( id serial, name varchar(30), created timestamp default now(), updated timestamp default now() ) サーブレット作成 下記ソースに直接説明を書いていく。 package controller; import java.io.IOException; import java.sql.Connection; データベースと接続するために必要 import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; 配列を使用するために必要 import java.util.HashMap; 連想配列を使用するために必要。  import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class ServeletReservation */ @WebServlet("/ServeletTodo") 左記がurlになる。 例えば、プロジェクト名/ServeletTodoとなる public class ServeletReservation extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public ServeletTodo() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { get送信された際に、このメソッドが走る // TODO Auto-generated method stub Connection conn = null; Statement stmt = null; ResultSet rset = null; try { //PostgreSQLへ接続 conn = connectDB(); //自動コミットOFF conn.setAutoCommit(false); //SELECT文の実行 stmt = conn.createStatement(); String sql = "select * from todos"; 一覧表示するためのリストを取得する ArrayList<HashMap> todoList = new ArrayList<>(); 配列作成 <>の中には、型を入れる rset = stmt.executeQuery(sql); //SELECT結果の受け取り while (rset.next()) {rset.next()がtrueの間はループする。これで全レコード取得 HashMap<String, String> hmap = new HashMap<String, String>(); キー:文字列 値:文字列の連想配列作成 String id = rset.getString("id"); DBからidカラムの値を取得 String task = rset.getString("name"); DBからnameカラムの値を取得 hmap.put("id", id); 上記で取得した値を連想配列のキーにセット hmap.put("task", task); 上記で取得した値を連想配列の値にセット これで、{'1', '英語学習'}のような連想配列が完成 todoList.add(hmap); 連想配列を配列に格納。 これをjspにて、forEachで一覧表示 } request.setAttribute("todos", todoList); todosというキーで上記で作成した配列を値としてセット。呼び出す時は、request.getAttribute("todos");とすることで可能 } catch (SQLException e) { e.printStackTrace(); } finally { try・catchが成功しても失敗してもここの処理に入る try { if (rset != null) rset.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } RequestDispatcher dispatch = request.getRequestDispatcher("index.jsp"); dispatch.forward(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {post送信の時はここの処理に入る // TODO Auto-generated method stub String method = request.getParameter("method"); // 追加 if (method.equals("POST")) { String task = request.getParameter("task"); doPost(task); } // 更新 if (method.equals("PUT")) { String id = request.getParameter("id"); Integer idInt = Integer.parseInt(id); String task = request.getParameter("task"); doPut(idInt, task); } // 削除 if (method.equals("DELETE")) { String id = request.getParameter("id"); Integer idInt = Integer.parseInt(id); doDelete(idInt); } doGet(request, response); } public void doPost(String task) { String sql = "insert into todos(name) values (?)"; sql作成 try { Connection conn = connectDB(); PreparedStatement stmt = conn.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS); stmt.setString(1, task); 上記sqlの❔部分に第二引数を当てはめる。ちなみに、第一引数は左から数えての❔の順番 stmt.executeUpdate(); } catch (SQLException e) { System.out.print("SQLException:" + e.getMessage()); } } public void doPut(Integer id, String task) { String sql = "update todos set name = ? where id = ?"; try { Connection conn = connectDB(); PreparedStatement stmt = conn.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS); stmt.setString(1, task); stmt.setInt(2, id); stmt.executeUpdate(); } catch (SQLException e) { System.out.print("SQLException:" + e.getMessage()); } } public void doDelete(Integer id) { String sql = "delete from todos where id = ?"; try { Connection conn = connectDB(); PreparedStatement stmt = conn.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS); stmt.setInt(1, id); stmt.executeUpdate(); } catch (SQLException e) { System.out.print("SQLException:" + e.getMessage()); } } public Connection connectDB() throws SQLException { //接続文字列 String url = "jdbc:postgresql://localhost:5432/test"; String user = "postgres"; String password = "test1212"; Connection conn = DriverManager.getConnection(url, user, password); return conn; } } jsp作成 <%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> forEachが使えるように導入 <%@ page isELIgnored="false"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>todo</title> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> </head> <body> <div class="container mx-auto"> <h1 class="text-center mb-4">todoリスト</h1> <div class="mx-auto w-25"> <!-- タスク追加欄 --> <div class="d-flex mb-4"> <div> <input type="text" id="js-task"> </div> <div style="margin-left: auto;"> <button id="js-add-task" class="ml-3">追加</button> </div> </div> <c:forEach var="todo" items="${todos}">request.setAttributeでセットしたキーをitemsに入れる。var="todo"配列の一つ一つの値が入っている <div class="d-flex mb-3"> <div> <input class="js-edit-task" type="text" value="${todo.task}" data-id="${todo.id}" /> </div> <div style="margin-left: auto;"> <button class="js-delete-task" data-id="${todo.id}">削除</button> </div> </div> </c:forEach> </div> </div> <div id="modal-overlay"></div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.3.1.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> <script>   /* タスク登録 */ $('#js-add-task').click(function() { var task = $('#js-task').val(); $.ajax({ url: './ServeletReservation', type: 'POST', data:{task: task, method: "POST"}, success: function(response) { alert("success"); location.reload(); }, error: function(response) { alert("error"); } }); }) /* タスク更新 */ $('.js-edit-task').change(function() { var task = $(this).val(); var id = $(this).data().id; $.ajax({ url: './ServeletReservation', type: 'POST', data:{task: task, id: id, method: "PUT"}, success: function(response) { alert("success"); location.reload(); }, error: function(response) { alert("error"); } }); }); /* タスク削除 */ $('.js-delete-task').click(function() { var id = $(this).data().id; $.ajax({ url: './ServeletReservation', type: 'POST', data:{id: id, method: "DELETE"}, success: function(response) { alert("success"); location.reload(); }, error: function(response) { alert("error"); } }); }); </script> </body> </html> 終わりに 著者は、サーバーサイド言語はphpしか経験がなかったので、javaを使用してwebサービスを作成することは非常に勉強になった。 具体的には、下記の点である 1、細かい違いはあれど、根幹の仕組みは、phpもjavaでも同じであり、根幹の仕組みさえ理解しておけばどの言語も習得可能であることが理解できるということ。 2、javaは、変数宣言の際に、型宣言が必要であったり、db接続の際などいちいちクラスをインポートしてメソッドを使わないといけないので、phpが比較的楽にコーディングできるということ。 これだけだとjavaのことはなにもわかっていない状態同然だと思うので、まだまだ理解を深めていきたいと思うし、 扱える言語を一つずつ増やしていきたいと思う。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Java] インターフェースとはなんぞや?

【Java】 interfaceとはなんぞや? よくわからないのでアウトプット. これがあってるのかはわからない..気をつけろ... interfaceとは? 見つけた限りでは メソッド名,引数,返り値のみを定義したもの 「このクラスは,〇〇というメソッドを持ちます」という「約束」 設計に一定の基準を設け,その基準を強制させるもの こんな奴らしい... いつ使うの? 今後沢山,仕様変更がありそうな時 大人数での開発 大型プロジェクト こんな時に使うそうだ. interfaceの目的 クラス間の依存度を下げたい 疎結合の実現 変更に強くしたい 観測した中で多かった意見. 仕様が生えてきたときにいっぱい変更したくない!!! 先に対策を打っておこうという感じだと思う. どういうこと? 具体?例で説明を試みる. 前提 チーム開発 interfaceを使わずに作った 誰かが作ったクラスAがクラスBからあるデータを受け取っていた ストーリー 仕様変更により,クラスCからデータを受け取るように変更しなければならなくなった. クラスCを作ったが,クラスAはクラスBからデータを受け取る前提だった,修正が必要に. クラスCの内容を知った上で,誰かが作ったクラスAを修正することになった. 何がまずいのか? 問題はクラスCの内容を知った上で,誰かが作ったクラスAを修正しなければならないことです. クラスAがクラスBに対する依存度が高いため,このようなことになってしまいました. しかも今度は,クラスCに対する依存度が高くなっています. 今後クラスDやE生えてきたら...大変ですね.. どうしたらよかったのか? クラスAとクラスBの間にinterfaceを設けておく クラスAはinterfaceに従って流れてきたデータを受け取ります. interfaceに従ってクラスCを実装すれば,クラスAを変更する必要がなくなります. 将来,クラスCをDやEに変更したとしてもinterfaceに従っている限り,クラスAはクラスEやDを知る必要がありません. 今後もクラスAはinterfaceに従って流れてきたデータを受け取るだけです. たぶん... 結局何が言いたい? 依存度を下げるために外側に規約を作っておけば,中身を知る必要はないぜ. しかも規約に従っとけば何してもおk って,事だと思う.みんな規約に従えば,ヨシ!!! その規約がinterface. ごめん,やっぱりよくわからなかったわ... 言葉だらけでお察しの通りよくわかってないです.. もう疲れたのでこのまま投げます. 参考文献 各所で引用されている神 https://www.gixo.jp/blog/5159/ teratail https://teratail.com/questions/70213 もうちょっと具体的な話が多い記事 https://engineer-club.jp/java-implements#implements3
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]Androidネイティブプラグイン(Java言語)

概要 Unity単体では使う事の出来ないAndroidの機能もAndroidプラグインを呼び出すことで使えるようになります。 この記事は、導入するための最小限のポイントをまとめたものです。詳しい解説は他の方の記事を参考にしてください(この記事の一番下にもリンクを貼っています) この記事はAndroidStudio4.0.1を使用しています。 1) プロジェクト作成 AndroidStudioを起動してFile > New > New Projectと進みます テンプレート選択画面ではNo Activity > Nextと進みます Nameに適当な名前を入力してください(Package nameは自動入力されます)LanguageはJavaを選びます 2) モジュール作成 File > New > New Moduleと進みます(New Moduleが押せない時はパソコンが処理してる最中なのでしばらく待ってみてください) Android Library > Nextと進みます 設定を確認してFinishを押します 3) appモジュールはいらないので削除します File > Project Structure 1)Modulesを選ぶと右の画面が切り替わります。 2)appが選択されているのを確認して『-』ボタンを押すとappの消去が決定されます 3)最後にOKを押します(OKを押さずにウィンドウを閉じると消去されないので注意してください) 4) Unityクラスライブラリを追加 Unityのプログラムフォルダ内にあるUnityクラスライブラリを貰ってきます スクリーンショットの様にProjectを選び libsを表示しておきます 環境によって違いますがUnityのプログラムフォルダをたどった先にあるclasses.jarを先ほどのlibsフォルダへコピーします(ドラッグアンドドロップするとファイルの移動になってしまいます。一度別のフォルダにコピーしてからそのファイルをlibsへドラッグアンドドロップすると上手くいきます) 5) モジュールレベルのbuild.gradleを修正する スクリーンショットの様にフォルダをたどりbuild.gradleをダブルクリックすると右の方にコードが表示されます。 コードを下にスクロールして implementation fileTree(dir: "libs", include: ["*.jar"]) この一行を compileOnly fileTree(dir: "libs", include: ["*.jar"]) と書き換えます。修正が終わったら右上のSync Nowを押します。成功するとSUCCESSFULと表示されるはずです。 6) プラグイン用のコードを作成する スクリーンショットの様にAndroidを選択します スクリーンショットの丸印のフォルダ上で右クリック > New > Java Class ポップアップが表示されるのでクラス名を入力します プラグインのコードを入力します Unity側から呼ばれるメソッドがFromUnity()で、このメソッドからUnity側のFromAndroid()を呼ぶことになります package com.example.mylibrary; import com.unity3d.player.UnityPlayer; public class PluginTest { public static String FromUnity() { UnityPlayer.UnitySendMessage("UnityTest" , "FromAndroid" , "メソッド呼び出し"); return( "戻り値" ); } } Build > Make Module プラグインが出力されたのでフォルダをたどって表示しておきます。 Unityでフォルダを作ります。 Assets > Plugins > Android 作成したフォルダに先ほどの出力されたプラグインをドラッグアンドドロップします。 UnityTest.csを新規作成してコードを記述します。 using UnityEngine; using UnityEngine.UI; public class UnityTest : MonoBehaviour { [SerializeField] Text txtMessage; [SerializeField] Button btnAndroid; void Start() { btnAndroid.onClick.AddListener(CallAndroidPlugin); txtMessage.text = "初期値"; } /// <summary> /// ボタンが押されたらプラグインを呼ぶ /// </summary> public void CallAndroidPlugin() { using (AndroidJavaClass androidJavaClass = new AndroidJavaClass("com.example.mylibrary.PluginTest")) { txtMessage.text += androidJavaClass.CallStatic<string>("FromUnity"); } } /// <summary> /// プラグイン側からUnityを呼ぶ /// </summary> public void FromAndroid(string str) { txtMessage.text += str; } } uGUIでテキストとボタンを用意します 空のオブジェクトを作って先ほど作ったUnityTestをAddComponentしてください AndroidのスマフォをパソコンにUSB接続してBuild And Runします(うまく出来ない時はスマフォ側の設定を変更する必要があるかもしれません) スマフォ画面で実行結果を確認します。ボタンを押すたびにAndroidプラグインを介して処理が行われることが確認できます。(ボタンを押すたびにテキスト文字が増え続けます) 参考にさせていただいた記事 こちらの記事の方が詳しくわかりやすく書かれています。自分のつまずいた箇所とバージョンの差による表示の違いをまとめるために今回記事にしてみました。 Unity向けAndroidネイティブプラグインの作り方 https://gaprot.jp/2020/03/30/unity-android-native-plugin/ 【Unity】Android Nativeプラグイン開発 最小構成でなるべくわかりやすくまとめた https://ghoul-life.hatenablog.com/entry/2019/01/26/030622 追記 プラグイン側のUnitySendMessageの引数は 第一引数 プラグイン側から呼び出したい「Unityのクラス名」 第二引数 プラグイン側から呼び出したい「Unityのメソッド名」 第三引数 呼び出したメソッドに渡す引数 UnityPlayer.UnitySendMessage("UnityTest" , "FromAndroid" , "メソッド呼び出し"); Unity側のAndroidJavaClassの引数は Java側のコードのpackageに指定されている部分 + クラス名 で記述します AndroidJavaClass("com.example.mylibrary.PluginTest")
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Iteratorでコレクションの要素を安全に削除する

対象読者 ・開発でJavaを使う方 ・Java中級者以上の方 ・その他、記事に興味のある方 本記事はどちらかというと中〜上級者の方向けの内容になっています。 ですが、できるだけ誰にでも読めるよう分かりやすく書いたので、プログラミングを勉強し始めたばかりの方もサッと読んでみて、そんなのあるんだ〜程度に覚えておいていただけると後々役に立つと思います?‍♂️ はじめに コレクションの要素を削除するには、拡張for文ではなくIteratorを使用する。 Javaを少し勉強した人なら、一度は聞いたことがある知識だと思います。しかし、ちゃんと理解できている人は案外少ないのではないでしょうか。 そこで本記事では、コレクションの要素を拡張for文で削除してはいけない理由や、Iteratorの使い方などについて詳しく解説していきたいと思います! 目次 ・コレクションとは ・ConcurrentModificationException ・Iterator ・拡張for文 ・Iteratorの使い方 コレクションとは まず、超簡単にコレクションについて説明します。 コレクションとは、複数の要素をまとめて扱うためのオブジェクトです。 コレクションの代表的なインタフェースとして、要素(重複可)を順序付けて管理するList、一意な要素を順不同で管理するSet、先入れ先だしの構造を持ったQueue、一意なキーと値(重複可)のペアを管理するMapの4つがあります。 階層構造は以下の通りです。 おそらく一番馴染みがあるのは、Listインターフェースの実装クラスであるArrayListでしょうか。 「コレクション」と言われてピンと来ない方は、ArrayListを想像していただければ大丈夫です! ConcurrentModificationException 次にConcurrentModificationException(以下、CMEと省略)についてです。 名前にconcurrent(訳:同時)、modification(訳:変更)と付いていますが、マルチスレッドだけでスローされる例外ではなく、シングルスレッドにおいてスローされる場合もあります。 公式APIを見るとCMEについて次のように書かれています。(一部抜粋) 単一のスレッドが、オブジェクトの規約に違反する一連のメソッドを発行した場合、オブジェクトはこの例外をスローします。たとえば、フェイルファスト・イテレータを持つコレクションの反復処理を行いながら、スレッドがコレクションを直接修正する場合、イテレータはこの例外をスローします。 ピンとこないと思います。公式APIってそういうものです...(笑) 噛み砕いて説明しますね。 コレクションは基本的にイテレータというものを持っているため、反復処理が可能です。イテレータとは、プログラミング言語において集合的データ構造(配列やコレクション)の各要素に対する繰り返し処理を表す概念です。イテレータにはフェイルファスト、弱一貫性、スナップショット、未定義という4つの分類があります。 このうち、ファイルファスト・イテレータを持つコレクションの反復処理中にコレクションの構造を変更(要素を削除するなど)すると、CMEがスローされるということです。 なお、Java.utilパッケージに属するほとんど全てのコレクションの持つイテレータは、フェイルファストです。 ちょっと難しいかもしれませんが、並行処理で使う特殊なコレクション以外は基本的にフェイルファストだと思っておけば大丈夫です。並行処理に使われるコレクションはjava.util.concurrentパッケージで提供されています。 Iterator Javaにおけるイテレータとはコレクション内の要素に順番にアクセスする手段です。要素を指し示すカーソルをイメージすると分かりやすいかもしれません。 Iteratorオブジェクトは、Iterableインタフェースのiterator()メソッドによって取得できます。 階層構造は下図のようになっており、Iterableインタフェースを継承するコレクションの各クラスで、iterator()を呼び出すことでIteratorオブジェクトを取得することができます。 Iterableインタフェースを実装したオブジェクトはイテレータを持つ(Iteratorを使用できる)ため、次に説明する拡張for文の対象にすることができます。 拡張for文 皆さんご存知の拡張for文ですが、拡張for文とはJava5でコレクションの反復処理を簡単に記述すべく導入されたものであり、内部的にはIteratorを使用しています。そのため、拡張for文はコンパイル時にIteratorを使用した処理へと書き換えられます。 ここでIteratorの実装を確認してみましょう。 Iteratorには、反復処理で次の要素を取り出すnext()メソッドというものがあり、next()メソッドは呼び出されるたびに内部でcheckForComodification()メソッドを実行します。 checkForComodification()メソッドでは、expectedModCount(Iteratorによりコレクションが変更された回数)とmodCount(実際にコレクションが変更された回数)という2つのフィールドの値を比較しており、2つの値に差異がある場合にCMEをスローします。 Iteratorのremove()メソッドを使用して要素を削除する場合は常に expectedModCount = modCount となるため例外は発生しません。 ただし、Iteratorのremove()メソッドを拡張for文から直接呼び出すことはできないため、拡張for文でコレクションに変更を加えるとexpectedModCountとmodCountの値に差異が生まれます。(Iteratorではコレクションを変更していないはずなのに、実際にはコレクションが変更されてしまっている状態になる。) これによりCMEが発生するというわけです。 そのため、例外を避けてコレクションの要素を削除したい場合には、Iteratorを明示的に使用すると良いでしょう。 前述したように、コレクションの反復処理中にIteratorのremove()メソッドを使用して要素が削除された場合に関しては、CMEがスローされることはありません。 以降、実例を交えながらIteratorの使い方について解説していきます! Iteratorの使い方 例として、「ArrayListの要素を削除する」というのを題材にIteratorの使い方を見ていきます。 Q.「今さらだけど、拡張for文じゃなくて普通のfor文使ったらダメなんですか...?」 → A.ダメです。理由については、こちらの記事の図解が分かりやすいので読んでみて下さい。 そもそも、SetやMapなどの要素を順序付けて管理していないコレクションにおいては、インデックスが存在しないため単純なfor文は使用できません。 for文とは違いIteratorの汎用性は高く、ほとんどのコレクションに使用できます。コレクションの種類に関わらず統一的な記述ができるというのはIteratorの大きなメリットです。 Iteratorの主なメソッドは以下の3つです。 boolean hasNext() 次の要素がある場合にtrueを返す。 E next() 次の要素を返す。 void remove() イテレータによって最後に返された要素を削除する。 それでは、これら3つのメソッドを使ってサンプルコードを書いてみます。 先ほどご紹介した記事の例題をそのまま使わせていただこうと思います。 例. リストに1, 2, 4, 6, 8, 9 という数を格納し、偶数の値のみリストから削除せよ。 //指定の要素を格納したリストを生成 List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 4, 6, 8, 9)); //listのiterator()を呼び出してIteratorオブジェクトを取得 Iterator<Integer> it = list.iterator(); while(it.hasNext()){ //イテレータが指し示す次の要素を取得 int i = it.next(); //取得した要素が偶数であれば削除する if(i % 2 == 0) { it.remove(); } } コードはたったのこれだけです。 最後まで読んでいただいてありがとうございました!背景知識は少し難しかったかもしれませんが、今回の目的であった、Iteratorでコレクションの要素を削除するという方法自体は簡単なので、是非使いこなせるようになって下さい(^^)!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring入門② Webjarsライブラリ追加

自分用の備忘録です。 Bootstrapを使用するため、Webjarsライブラリをプロジェクトに追加 <!-- 追加開始 --> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>1.11.1</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7-1</version> </dependency> <!-- 追加終了 --> ※Bootstrapの一部にはjQueryが使用されてるため、一緒に追加する必要がある。 追加後はMavenの更新を行う
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【祝!東日本GA】Azure Spring Cloud をとにかく始めてみる

@yo41sawada です。 前回 こちらの記事 で Azure Spring Cloud に注目しているといった矢先、 嬉しいニュースが飛び込んできました。 というわけで早速試してみたので、それを共有しようと思います。 この記事で共有すること Azure Spring Cloud を東日本リージョンにデプロイするための大まかな手順とその画面キャプチャ この記事で言及しないこと Azure(ポータル/ CLI ) の基本的な操作・用語や Microsoft アカウントを準備するための手順 Java & Spring を用いた基本的なウェブアプリケーション開発や Maven を用いたビルドに関する知識や手順 動作環境 動作環境は以下の通りです。ちなみに今回 Java については、こちらも先日発表になった Microsoft 独自の OpenJDK ディストリビューションである「Microsoft Build of OpenJDK」を使っています( 2021 年 4 月 15 日時点ではプレビュー版)。それはまた別の機会があれば。 OS : Windows 10 Pro (19042.867) Java : Microsoft Build of OpenJDK 11.0.10 Maven : 3.8.1 Azure CLI : 2.17.1 全体の流れ 先に大まかな流れを押さえておきましょう。 環境セットアップ( Java / Maven / Azure CLI ) デプロイする Spring Web アプリケーションの準備 東日本リージョンへの Azure Spring Cloud リソース追加 上記リソースへのアプリ追加 ビルドしたアプリケーション(jar)のデプロイ 環境セットアップ( Java / Maven / Azure CLI ) 詳細な手順は省きますが、今回はコマンド( Git Bash )を用いる部分もあるので、 正しくインストール出来ているかを確認するようにしましょう。 Java Microsoft Build of OpenJDK は こちら からダウンロードページに遷移し(「 Download 」ボタンをクリック)、インストーラをダウンロードしてインストールします。 私の場合は、以下のインストーラを用いました。 microsoft-jdk-11.0.10.9-windows-x64.msi インストールが完了したら、 Git Bash にて以下のコマンドを実行して JDK がインストールされていることを確認します。 $ java -version 例えば以下のように表示されれば成功です。 openjdk version "11.0.10" 2021-01-19 OpenJDK Runtime Environment Microsoft-18724 (build 11.0.10+9) OpenJDK 64-Bit Server VM Microsoft-18724 (build 11.0.10+9, mixed mode) Maven Maven の場合は こちら からアーカイブファイルをダウンロードした後、解凍して環境変数の設定を行います。 私の場合は、以下のアーカイブファイルを用いました。 apache-maven-3.8.1-bin.zip 解凍と環境変数の設定が完了したら、 Git Bash にて以下のコマンドを実行して mvn コマンドが実行できることを確認します。 $ mvn -v 例えば以下のように表示されれば成功です。 Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d) Maven home: C:\develop\apache-maven-3.8.1 Java version: 11.0.10, vendor: Microsoft, runtime: C:\Program Files\Microsoft\jdk-11.0.10.9-hotspot Default locale: ja_JP, platform encoding: MS932 OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows" Azure CLI Azure CLI は こちら からダウンロードページに遷移し(「〇〇へのインストール」リンクをクリック)、インストーラをダウンロードしてインストールします。 私の場合は、以下のインストーラを用いました。 azure-cli-2.17.1.msi インストールが完了したら、 続けて以下のコマンドを実行して Azure CLI 用の Azure Spring Cloud 拡張機能をインストールします。 $ az extension add --name spring-cloud インストールが完了したら、以下のコマンドを実行して Azure CLI と Azure Spring Cloud 拡張機能がインストールされていることを確認します。 $ az --version 例えば以下のように表示されれば成功です。私の場合は更新のアナウンスが表示されていますが、これは記事執筆時点での Azure CLI 最新バージョンが 2.22.0 であるためです。ここではそのまま続けていきますが、入手できる最新の Azure CLI を用いても問題無いと思います。 azure-cli 2.17.1 * core 2.17.1 * telemetry 1.0.6 Extensions: spring-cloud 2.3.1 Python location 'C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\python.exe' Extensions directory 'C:\Users\{USER NAME}\.azure\cliextensions' Python (Windows) 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 23 2018, 23:31:17) [MSC v.1916 32 bit (Intel)] Legal docs and information: aka.ms/AzureCliLegal You have 2 updates available. Consider updating your CLI installation with 'az upgrade' Please let us know how we are doing: https://aka.ms/azureclihats and let us know if you're interested in trying out our newest features: https://aka.ms/CLIUXstudy そのまま Microsoft アカウントでログインしましょう。 $ az login デプロイする Spring Web アプリケーションの準備 環境のセットアップが完了したら、早速 Azure Spring Cloud 向けアプリケーションを用意していきましょう。ここではイチから準備する方法とショートカットする方法を紹介しますが、問題無くビルドして jar を作成できることがゴールです。 イチから イチから準備する場合は、公式のドキュメントに方法が記載されているので、その通り進めていきましょう。 まずは Spring Initializr にアクセスし、プロジェクトを準備します。こちら から Spring Initializr へアクセスすれば予め Azure Spring Cloud 向けの Dependencies を追加したプロジェクトが設定されているので、「 GENERATE 」 ボタンをクリックしてアーカイブをダウンロードしてください。 ダウンロードが完了したらそのアーカイブを一度解凍し、 HellospringApplication.java と同じディレクトリに API 用の HelloController.java を用意します。 HelloController.java package com.example.hellospring; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; @RestController public class HelloController { @RequestMapping("/") public String index() { return "Welcome to Japan East!!!"; } } HelloController.java の準備が出来たら、Maven を使ってプロジェクトをビルドします。 $ mvn clean package 面倒な方向け ドキュメントや上記に記載した内容を読んで進めることを省略したい方は、 こちら からサンプルプロジェクトをダウンロードなりクローンなりした上でビルドしてください。 東日本リージョンへの Azure Spring Cloud リソース追加 それではいよいよ東日本リージョンの Azure Spring Cloud リソースを追加していきます。 Azure ポータル に Microsoft アカウントを用いてログインし、ホーム画面にて「リソースの作成」をクリックします。 「新規」ページの「 Marketplace を検索」フォームに、「 Azure Spring Cloud 」と入力します。 検索結果に表示された「 Azure Spring Cloud 」の「作成」をクリックします。 表示された「 Azure Spring Cloud 」リソース作成画面の「基本」タブにて以下を入力します。 プロジェクトの詳細 サブスクリプション(例:Pay-As-You-Go ) リソースグループ(例:RG_Demo4ASC ) サービスの詳細 名前(例:welcome-japaneast-asc ) リージョン(東日本)←当然 価格(例:Basicレベル) タブを下にスクロールし、「確認と作成」をクリックします。 問題無く検証が終了したことを確認し、「作成」をクリックします。 リソースのデプロイ画面が表示されるので、完了を待ちます。なおこの辺りから「 Microsoft.AppPlatform 」という表現が出てきますが、気にせず進めて下さい。 作成された Azure Spring Cloud のリソースを確認します。 上記リソースへのアプリ追加 続いて、準備した東日本リージョンの Azure Spring Cloud リソースへ、アプリを追加していきます。 Azure Spring Cloud リソースの 「設定」 > 「アプリ」に、何も表示されていないことを確認します。 Git Bash を起動し、以下のコマンドを実行することでアプリを追加します。先ほど作成したリソースを例にあげると、以下のようになります。 アプリ名(例.hellospring )← ここだけ考える サービス名( welcome-japaneast-asc ) リソースグループ名( RG_Demo4ASC ) $ az spring-cloud app create -n アプリ名 -s サービス名 -g リソースグループ名 --assign-endpoint true コマンドの実行結果に「 App create succeeded 」と表示されていれば、アプリの追加は成功です。 再度 Azure ポータルに戻り、 Azure Spring Cloud リソースの 「設定」 > 「アプリ」において、追加したアプリ(例.hellospring )が表示されていることを確認します。 追加したアプリ名のリンクをクリックし、「概要」に表示された「URL」をクリックします。 Azure Spring Cloud のページが表示されていることを確認します。 ビルドしたアプリケーション(jar)のデプロイ 最後に、追加したアプリに先程ビルドした jar をデプロイしていきます。 Git Bash を起動し、以下のコマンドを実行することでアプリへ jar をデプロイします。先ほど追加したアプリを例にあげると、以下のようになります。 アプリ名( hellospring ) サービス名( welcome-japaneast-asc ) リソースグループ名( RG_Demo4ASC ) ビルドした jar の配置されているパス(例:target/hellospring-0.0.1-SNAPSHOT.jar ) $ az spring-cloud app deploy -n アプリ名 -s サービス名 -g リソースグループ名 --jar-path ビルドした jar の配置されているパス コマンドが問題無く終了していれば、デプロイは成功です。 先程と同様に Azure Spring Cloud リソースへ追加したアプリ名のリンクをクリックし、「概要」に表示された「URL」をクリックします。 API のレスポンスが正しく返っていることを確認します。 以上が東日本リージョンの Azure Spring Cloud にアプリケーションをデプロイする手順です。うまくいきましたか? ハマりやすいところ 最後に少しだけ、ハマりやすいところ(自分が進めていて不安になったところや少し躓いたところ)を紹介しておきますので、他にもあればコメントなど頂けると嬉しいです。 リソースのデプロイに 20 分くらいかかった Azure ポータルを用いて Azure Spring Cloud リソースを追加した際のデプロイに 20 分程時間がかかりました。東日本リージョンだからなのかは切り分けできていませんが、ここは気長に待ちましょう。 ResourceNotFoundError に遭遇した 「az spring-cloud app create ~」コマンドを実行した時に、リソースグループ名が見つからないというエラーに遭遇しました。これは Azure CLI コマンドを操作している方は一度は遭遇するのではというあるあるなのですが、Azure CLI を操作している際にログインしている Microsoft アカウントのサブスクリプションが適切に指定されていない場合等に起こります。焦らず、以下のようにサブスクリプションを指定するコマンドを実行しましょう。サブスクリプションは適宜読み替えてください(例:Pay-As-You-Go )。 $ az account set -s サブスクリプション名 ビルドしたアプリケーションをデプロイしたのに変化が無い 正しくデプロイできているのであれば、ブラウザのキャッシュが原因です。落ち着いて、F5 等でリロードしましょう。 おわりに いかがだったでしょうか。Spring や Azure を触っている方であれば、東日本リージョンに Azure Spring Cloud のアプリケーションを簡単にデプロイできたのではないかと思います。一方でここで紹介しなかった機能や画面も多いので、例えば以下のような内容について確認出来たら、こちらで共有していこうと思います。 価格レベルの変更 Automation 有効化 Java インプロセスエージェント有効化 既存の仮想ネットワークへのデプロイ 関連記事等 クイック スタート:初めての Azure Spring Cloud アプリケーションをデプロイする 30 分でわかった気になれる Azure Spring Cloud マイクロソフトが無償でJavaの長期サポートを提供へ、「Microsoft Build of OpenJDK」をリリース
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

public static void mainとは

初めに Javaを勉強すると最初にぶつかる壁といえば、Public static void main(String[]args) でしょうか。 私自身Java学習を開始して間もないですが、意味が分からず苦戦しています。 そこで、この構文の意味を調べてみました。 他の初学者様の参考になればと思います。 main メソッドについて 初めに、Public static void main(String[]args)の"main"に関してです。 これはメソッド名を示します。 そして、mainと名付けられたメソッドには初期設定として2つの役割が与えられます。 1つ目の役割は、コマンドライン(黒い画面)でプログラムを起動したタイミングで自動的に実行されるという事。 2つ目の役割を、他クラス(設計図)を使いオブジェクトの作成や操作を行うという事。 以上2つの役割を頭の隅に入れながら以下の説明を読んでいただけたらと思います。 staticについて インスタンス化(クラスと呼ばれる設計図を参考に、データを作る事)をしなくても、 使える事を意味します。 プログラム実行のタイミングで起動する役割がありますので、データを作る前に実行 しなくてはいけないわけです。 voidについて 戻り値が無いことを意味します。 戻り値とは、呼び出し先に渡す処理結果の事です。 mainメソッドは他クラスを利用する事はあっても、利用されることはありません。 何故なら自動的に実行されるからです。 したがって、呼び出し先に値を渡す事態は起きず、戻り値は不要となります。 String[]argsについて コマンドライン引数と呼ばれる引数です。 コマンドラインから渡す引数であり、文字列が打たれる事が想定されています。 なのでデータ型(データを入れる箱の種類)はString[]と呼ばれる文字列を保存するものになっています。 では、何故コマンドライン引数で値を渡す必要があるのか。 それはmainメソッドが一番最初に自動実行されるからです。 他クラスで引数を指定してメソッドを実行する事が出来ません。 そこで、コマンドラインでプログラム実行命令と一緒に引数も指定する必要が出てきました。 これがコマンドライン引数とString[]が使用される理由です。 ※argに関しては慣例で使用されているだけなので、別の文字でも構いません。 最後に 初めての投稿になりますが、初学者さんの手助けになれば幸いです。 私自身Javaの学習を開始して日が浅いので間違いなどあればご指導お願い致します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】public static void mainとは

初めに Javaを勉強すると最初にぶつかる壁といえば、Public static void main(String[]args) でしょうか。 私自身Java学習を開始して間もないですが、意味が分からず苦戦しています。 そこで、この構文の意味を調べてみました。 他の初学者様の参考になればと思います。 main メソッドについて 初めに、Public static void main(String[]args)の"main"に関してです。 これはメソッド名を示します。 そして、mainと名付けられたメソッドには初期設定として2つの役割が与えられます。 1つ目の役割は、コマンドライン(黒い画面)でプログラムを起動したタイミングで自動的に実行されるという事。 2つ目の役割を、他クラス(設計図)を使いオブジェクトの作成や操作を行うという事。 以上2つの役割を頭の隅に入れながら以下の説明を読んでいただけたらと思います。 staticについて インスタンス化(クラスと呼ばれる設計図を参考に、データを作る事)をしなくても、 使える事を意味します。 プログラム実行のタイミングで起動する役割がありますので、データを作る前に実行 しなくてはいけないわけです。 voidについて 戻り値が無いことを意味します。 戻り値とは、呼び出し先に渡す処理結果の事です。 mainメソッドは他クラスを利用する事はあっても、利用されることはありません。 何故なら自動的に実行されるからです。 したがって、呼び出し先に値を渡す事態は起きず、戻り値は不要となります。 String[]argsについて コマンドライン引数と呼ばれる引数です。 コマンドラインから渡す引数であり、文字列が打たれる事が想定されています。 なのでデータ型(データを入れる箱の種類)はString[]と呼ばれる文字列を保存するものになっています。 では、何故コマンドライン引数で値を渡す必要があるのか。 それはmainメソッドが一番最初に自動実行されるからです。 他クラスで引数を指定してメソッドを実行する事が出来ません。 そこで、コマンドラインでプログラム実行命令と一緒に引数も指定する必要が出てきました。 これがコマンドライン引数とString[]が使用される理由です。 ※argに関しては慣例で使用されているだけなので、別の文字でも構いません。 最後に 初めての投稿になりますが、初学者さんの手助けになれば幸いです。 私自身Javaの学習を開始して日が浅いので間違いなどあればご指導お願い致します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java開発環境で気になったところをまとめてみた

Java開発環境についてあまり知らないなと思い少しまとめてみました。 Java開発環境を大きく分けて3つあります。 IDE(Intergrated Development Enviroment):統合開発環境 現場ではこの開発ツールを利用することが一般的です。 エディタ、コンパイラ、インタプリンタなど全て内臓されたソフトウェアです。 これ1つあれば大体のことは可能だと言えます。 代表的な製品:Eclipse,NetBeansなど JDK(Jave Development Kit):Java開発道具一式 Java のプログラムの開発や実行を行うためのプログラムのセットです。 JDK をインストールすることで Java を使ったアプリケーションの作成や作成したアプリケーションの実行まで 一通り行うことができます。 JRE(Java Runtime Environment):java実行環境 Java のプログラムを実行するためのセットです。 JRE をインストールすることで 作成したアプリケーションの実行ができるようになります。 プログラムを実行するために必要4つあります。 インタプリタ 人間語(ソースコード)を1行1行読んでを機械語(バイトコード)に変換するソフトウェアのこと。 厳密に言うとインタプリタはJVMという仕組みを内部に持っています。 JVM(Java Virtual Machine):Java仮想マシン 対象となるOSで実行可能な形式のコードに変換して動かすことができる。 Javaで作ったプログラムをプラットフォームに依存しないで動かすためにJVMが必要になります。 コンパイラ 人間語(ソースコード)を一気に機械語(バイトコード)に変換するソフトウェアのこと。 javac (Java compiler):Javaコンパイラ コンパイルするコマンドのこと。 ※コンパイル・・・人間語(ソースコード)を機械語(バイトコード)に変換する作業のこと。 エディタ ソースコードを書く場所のこと。 JavaSE(Java Platform, Standard Edition) Java の基本となる APIを まとめたもの。それ以外にJavaEE、JavaMEも存在する。 ※JavaEE・・・JavaSE + そこにサーバーサイド機能を追加したもの。  JavaME・・・JavaSE + 家電などの組み込み機器やモバイルデバイスで動作する機能を         追加したもの。 API(Application Programming Interface) Javaでアプリケーションを作成するために必要となる標準機能を提供するインタフェースのこと。簡単にいうとJavaの機能が簡単に使えるようになる。 また気になることがあったら更新していこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring入門① 新規スタータープロジェクト立ち上げ時

新規立ち上げ時に選択しておくべきライブラリ一覧 自分用の備忘録です。 Spring Boot Devtools ...javaファイルを修正したとき、自動でアプリを再起動してくれる Lombok ...@Dataアノテーションをつけることで、getter,setterなどを自動生成してくれる Spring Data JDBC,PostgreSQL Driver ...PostgreSQLに接続する際に必要 Thymeleaf ...HTMLのテンプレートエンジンが使える SpringWeb ...SpringMVC,SpringBootが使えるようになる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む