AJ(あじ)ブログ

IT系の記事中心になります。

【Java】初心者向け クラス(Object)の複製(コピー)について


Javaのコピーについておさらいのため、作成してみました。

POINTとしてはimmutableでないものを代入(=)で複製(コピー)を行うと参照が同じとなってしまうということです。
なので、Cloneメソッドを使用するようにしましょうということです。(独自に作成したクラスの場合はCloneメソッドを作成する)


今回はコピーに関するコードを作成して”paiza.io”で試してみました。
※コメントがあればちゃんと解説します。

▼コード

import java.util.*;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        SampleClass sample = new SampleClass();
        sample.Start();
    }
}

class SampleClass {
    private String SEPARATE = "---------------------";
    private String LOG_STRING = "▼▼ 結果 ▼▼";
    public void Start(){
        // 飲み物クラスの初期化
        System.out.println(SEPARATE);
        Drink carbonatedWater = new Drink("carbonated water","炭酸水","水");
        System.out.println(carbonatedWater);

        // Drink 代入
        System.out.println(SEPARATE);
        System.out.println("NGパターン1");
        System.out.println("飲み物 carbonatedWater をコピーして lightlyCarbonated を作成(代入)");
        System.out.println("=で代入しただけでは同じObjectを参照しているため、carbonatedWater の値も変わってしまう。");
        Drink lightlyCarbonated = carbonatedWater;
        lightlyCarbonated.name = "lightly carbonated";
        lightlyCarbonated.detail = "炭酸水(微炭酸)";

        System.out.println(LOG_STRING);
        System.out.println(carbonatedWater);
        System.out.println(lightlyCarbonated);

        // Drink new
        System.out.println(SEPARATE);
        System.out.println("NGパターン2");
        System.out.println("飲み物 Drinkをnewして carbonatedWater の値を設定して soda を作成(クラスだけnew)");
        System.out.println("OK : newでDrinkを作成したので、IDは別物になっている。また、Stringはイミュータブルなので同じく別物になっている。");
        System.out.println("NG : ingredient(ArrayList<String>)は同じObjectとなってしまうため、carbonatedWater の値も変わってしまう。");

        Drink soda = new Drink(carbonatedWater);
        soda.name = "soda";
        soda.detail = "ソーダ";
        soda.ingredient.add("砂糖");

        System.out.println(LOG_STRING);
        System.out.println(carbonatedWater);
        System.out.println(lightlyCarbonated);
        System.out.println(soda);

        // Drink Clone
        System.out.println(SEPARATE);
        System.out.println("Drinkをcloneする Drinkクラスに Cloneableを継承して clon メソッドを作成して、Objectの複製時はCloneを使用するようにする。(Clone)");
        System.out.println("※Drink.clone内でingredient(ArrayList<String>)のcloneも行うようにしています。");
        System.out.println("Clone(複製)なのでIDは同じとなっている。");
        try {
            Drink appleSoda = soda.clone();
            appleSoda.name = "Apple Soda";
            appleSoda.detail = "りんごソーダ";
            appleSoda.ingredient.add("りんご");

            System.out.println(LOG_STRING);
            System.out.println(carbonatedWater);
            System.out.println(lightlyCarbonated);
            System.out.println(soda);
            System.out.println(appleSoda);
        }
        catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
    }
}

class Drink implements Cloneable {
    UUID id = UUID.randomUUID();
    public String name;
    public String detail;
    public ArrayList<String> ingredient;

    Drink(String name,String detail,String... ingredient){
        this.name = name;
        this.detail = detail;
        this.ingredient = new ArrayList<>(Arrays.asList(ingredient));
    }

    Drink(Drink drink){
        this.name = drink.name;
        this.detail = drink.detail;
        this.ingredient = drink.ingredient;
    }

    public String toString(){
        return String.format("ID:%s,名前:%s,詳細:%s,成分:%s (ID:%s,名前:%s,詳細:%s,成分:%s)",
                id,
                name,
                detail,
                ingredient.toString(),
                System.identityHashCode(id),
                System.identityHashCode(name),
                System.identityHashCode(detail),
                System.identityHashCode(ingredient)
        );
    }

    @Override
    public Drink clone() throws CloneNotSupportedException{
        Drink clone = (Drink)super.clone();
        clone.ingredient = (ArrayList<String>) this.ingredient.clone();
        return clone;
    }
}

▼実行結果

---------------------
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:carbonated water,詳細:炭酸水,成分:[水] (ID:930990596,名前:1921595561,詳細:565760380,成分:6566818)
---------------------
NGパターン1
飲み物 carbonatedWater をコピーして lightlyCarbonated を作成(代入)
=で代入しただけでは同じObjectを参照しているため、carbonatedWater の値も変わってしまう。
▼▼ 結果 ▼▼
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:lightly carbonated,詳細:炭酸水(微炭酸),成分:[水] (ID:930990596,名前:787604730,詳細:812265671,成分:6566818)
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:lightly carbonated,詳細:炭酸水(微炭酸),成分:[水] (ID:930990596,名前:787604730,詳細:812265671,成分:6566818)
---------------------
NGパターン2
飲み物 Drinkをnewして carbonatedWater の値を設定して soda を作成(クラスだけnew)
OK : newでDrinkを作成したので、IDは別物になっている。また、Stringはイミュータブルなので同じく別物になっている。
NG : ingredient(ArrayList<String>)は同じObjectとなってしまうため、carbonatedWater の値も変わってしまう。
▼▼ 結果 ▼▼
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:lightly carbonated,詳細:炭酸水(微炭酸),成分:[水, 砂糖] (ID:930990596,名前:787604730,詳細:812265671,成分:6566818)
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:lightly carbonated,詳細:炭酸水(微炭酸),成分:[水, 砂糖] (ID:930990596,名前:787604730,詳細:812265671,成分:6566818)
ID:ba2f7be6-2340-446c-8011-bfdfa8cd5887,名前:soda,詳細:ソーダ,成分:[水, 砂糖] (ID:193064360,名前:109961541,詳細:670700378,成分:6566818)
---------------------
Drinkをcloneする Drinkクラスに Cloneableを継承して clon メソッドを作成して、Objectの複製時はCloneを使用するようにする。(Clone)
※Drink.clone内でingredient(ArrayList<String>)のcloneも行うようにしています。
Clone(複製)なのでIDは同じとなっている。
▼▼ 結果 ▼▼
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:lightly carbonated,詳細:炭酸水(微炭酸),成分:[水, 砂糖] (ID:930990596,名前:787604730,詳細:812265671,成分:6566818)
ID:31b43f8b-c595-4bce-9a12-d7562098a2b2,名前:lightly carbonated,詳細:炭酸水(微炭酸),成分:[水, 砂糖] (ID:930990596,名前:787604730,詳細:812265671,成分:6566818)
ID:ba2f7be6-2340-446c-8011-bfdfa8cd5887,名前:soda,詳細:ソーダ,成分:[水, 砂糖] (ID:193064360,名前:109961541,詳細:670700378,成分:6566818)
ID:ba2f7be6-2340-446c-8011-bfdfa8cd5887,名前:Apple Soda,詳細:りんごソーダ,成分:[水, 砂糖, りんご] (ID:193064360,名前:1190654826,詳細:1109371569,成分:728890494)

▼paiza.io
paiza.io

【便利ツール】Squoosh(画像圧縮ツール)

画像サイズを小さくしたいときに便利なツールです。
優秀なツールなので、劣化が少なく、画像サイズを減らすことができます。

私は、iPhoneで撮影した画像をはてなブログにアップロードする際にそのままではサイズが大きすぎるため
このSquoosh使用してサイズを小さくしています。

↓こんな感じで劣化度合いを確認しながら、簡単に圧縮率を変更できるので、使いやすいです。

Squoosh

【たまには休憩】在宅ワークのお供


最近では在宅で仕事をされている方も多いのではないかと思います。
そこで、個人的にハマっているおすすめのアイテムを紹介したいと思います。

■紙のお香 Papier d’Arménie
画像のように、切り離してから蛇腹に折り目をつけてから火をつけて香りを楽しみます。
#個人的にはトラディショナルが一番好きです
紙を燃やすので、火には気をつけて扱ってください。
画像で使用している受け皿は無印良品の商品を使用しています。

Papier d’Arménie

Amazon等でも販売されています。
amzn.to


■Daelmans(ダールマンズ) Stroopwafels
頭を使っていると甘いものが欲しくなりますよね。

この商品は、そのまま食べても美味しいのですが
コーヒーを注いだカップの上にのせてしばらく置くと、中のキャラメルフィリングがとろけて最高です。
#ネットでも購入できますが、カルディでも販売しているので私はカルディで購入しています。

Amazon等でも販売されています



在宅期間が長くなり、いろいろおすすめしたいものがあるので
定期的に公開したいと思います。

VoiceAnalysisプライバシーポリシー

App Privacy Policy Generator
Generate a generic Privacy Policy and Terms & Conditions for your apps
Built with heart by Nishant and contributors.

TwitterDisclaimerGitHub stars


While App Privacy Policy Generator is completely FREE, it takes money to keep it running and updated.
If you are able to, then consider contributing by:

Sponsoring me on Github 👨🏻‍💻
Buying me a cup of ☕
If you are unable to contribute with funds, consider sharing it with your friends: Twitter, Linkedin, Facebook, Reddit

...or adding a review/comment in the project's GuestBook 🤗

All Done!
Now sit back and choose the type of document you want to generate:




The accuracy of the generated privacy policy and terms & conditions on this website is not legally binding. Use at your own risk.

Read the full Disclaimer here


Privacy Policy
Jin Okamoto built the VoiceAnalysis app as a Free app. This SERVICE is provided by Jin Okamoto at no cost and is intended for use as is.

This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service.

If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy.

The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which are accessible at VoiceAnalysis unless otherwise defined in this Privacy Policy.

Information Collection and Use

For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request will be retained on your device and is not collected by me in any way.

The app does use third-party services that may collect information used to identify you.

Link to the privacy policy of third-party service providers used by the app

AdMob
Log Data

I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third-party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics.

Cookies

Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory.

This Service does not use these “cookies” explicitly. However, the app may use third-party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.

Service Providers

I may employ third-party companies and individuals due to the following reasons:

To facilitate our Service;
To provide the Service on our behalf;
To perform Service-related services; or
To assist us in analyzing how our Service is used.
I want to inform users of this Service that these third parties have access to their Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.

Security

I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security.

Links to Other Sites

This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.

Children’s Privacy

These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13 years of age. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do the necessary actions.

Changes to This Privacy Policy

I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page.

This policy is effective as of 2022-06-19

Contact Us

If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me at aj.lab.app@gmail.com.

This privacy policy page was created at privacypolicytemplate.net and modified/generated by App Privacy Policy Generator

ブログへのアクセスと広告収入

広告収入について勉強も兼ねて登録してみたのですが、
いまいち各種アクセス数との関係がわからず難しいです。

今回、はてなブログ上でのアクセス数だけ伸びていて
Google Search Console上では伸びていないため、ブラウザからのアクセスではなく
スクレイピングツールなどからクローリングされているのではと考えています。
今後も定期的にチェックして、アクセス数の分析について分かり次第追記したいと思います。
#各種のアクセス数の違いについてわかる方がいましたらコメントいただきたいです。

はてなブログアクセス解析画面 でのアクセス数
6/4 が51となっている。

はてなブログアクセス

Google AdSense でのアクセス数
6/4 が表示回数7(ページビュー2)

GoogleAdアクセス

Google Search Console でのアクセス数
6/4 が表示回数12(クリック数3)となっている

GoogleSearchアクセス
個人制作アプリリリース中「TimePost」
Download on the App Store
個人制作アプリリリース中「UrlReader」
Download on the App Store