ぱぴブログ

さんたろのブログ

ゲーム開発が好きな人のひとりごと

Java奮闘記3 コレクションと配列 インターフェース

はじめに

環境などは以下の記事を参考にしてほしい。
papyrustaro.hatenablog.jp

コレクションと配列

概要

複数の要素の集まりを扱うもの。
データ構造とアルゴリズムの知識があれば理解も早まる。

サンプルコード

import java.util.*;
class Tester{
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("AAA");
        list.add("BBB");
        list.add("CCC");
        
        for(String s : list) {
            System.out.println(s);
        }
    }
}

コレクションの要素の型には任意の参照型を指定できる。
基本型は指定できない

リスト

Listインターフェースのメソッド

詳しくは以下のサイトをご覧いただきたい。
docs.oracle.com

・add ... リストの最後に要素を追加
・addAll ... まとめて追加
・contains ... 指定要素が含まれていたらtrue
・get(int index) ... 指定indexにある要素の取得
・indexOf ... 指定した要素が最初に見つかった位置のindexの取得
・lastIndexOf ... 後方から探索
・remove ... 指定要素を探索し、最初に見つけた要素を削除。なければ変更なし
・set(int index, E element) ... 指定したindexにある要素を、指定要素にする
・size ... 要素数を返す
・subList(int fromIndex, int toIndex) ... fromIndex以上toIndex未満の部分のリストを取得

サンプルコード

import java.util.*;
class Tester{
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        
        list.add("AAA");
        list2.add("BBB");
        list2.add("CCC");
        list.addAll(1, list2);
        System.out.println(list.get(2));
        System.out.println(list.indexOf("BBB"));
        list.remove(0);
        list.set(0, "DDD");
        System.out.println(list.size());
        
        for(String s : list) {
            System.out.println(s);
        }
    }
}
リストの具象クラス

ArrayList ... 配列を使ったもの。index指定の動作は得意
・LinkedList ... Nodeを使ったもの。要素の挿入、削除が得意
ここはCの配列とリストの差と変わりませんね。

マップ

keyとvalueを1セットで管理。この1セットでマップの要素となる。

Mapインターフェースのメソッド

詳しくは以下のサイトをご覧いただきたい。
docs.oracle.com

・containsKey ... 指定したキーが存在すればtrue
・containsValue ... 指定した値が存在すればtrue
・compute ... 指定したキーの既存要素を使って新要素追加
・computeIfAbsent ... 指定したキーが存在しなければ要素追加
・computeIfPresent ... 指定したキーがあれば要素追加
・forEach ... 要素ごとに指定処理実行
・get ... 指定したキーで値検索
・keySet ... キーの集合を取得
・put ... 要素追加
・putAll ... 要素をまとめて追加
・putIfAbsent ... 指定したキーがなければ要素追加
・remove ... 要素を削除
・replace ... 指定したキーの値を置換
・replaceAll ... 要素を置換
・size ... 要素数の取得
・values ... 値の集合を取得

マップの具象クラス

・HashMap ... 追加や検索がはやい。順序は持てない
・LinkedHashMap ... 追加やアクセスの順序を持つことができる。
・TreeMap ... 任意の比較規則に基づいた順序を持つことができる。

サンプルコード

import java.util.*;
class Tester{
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        
        map.put("Frisk", 103);
        map.put("Papyrus", 183);
        map.put("Sans", 132);
        map.remove("Frisk");
        map.replace("Papyrus", 178);
        map.compute("Sans", (key, old) -> old + 10);
        
        //Sans : 142
        //Papyrus : 178
        map.forEach((key, value) -> System.out.println(key + " : " + value));
    }
}

イテレータ

イテレータの概要

イテレータとは、繰り返し処理を抽象化したオブジェクトのこと。
コレクション自体に順序の概念がないとき、要素を一つずつ取り出すこと。

Iteratorインターフェースのメソッド

詳しくはこちらのサイト↓
docs.oracle.com

・hasNext ... まだ取り出す要素があるならtrue
・next ... 次の要素を返す
・remove ... nextで取り出した要素をコレクションから削除する
・forEachRemaining ... すべての要素の処理が完了するまで残りの要素に指定されたアクションをする

サンプルコード

import java.util.*;
class Tester{
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        
        map.put("Frisk", 103);
        map.put("Papyrus", 183);
        map.put("Sans", 132);
        
        for(Iterator<String> it = map.keySet().iterator(); it.hasNext(); ) {
            String key = it.next();
            System.out.println(key);
        }
        
        Iterator<String> it = map.keySet().iterator();
        it.forEachRemaining(e -> System.out.println(e));
    }
}

Collectionsクラス

Collectionsクラスはコレクションに対する様々なメソッドを提供している。
詳しくはこちら↓
docs.oracle.com

コレクションの初期化記法

①asListを使った方法

List<StringBuilder> list = Arrays.asList(new StringBuilder("AA"), new StringBuilder("BB"));

これで生成されるListは固定サイズのArrayListであるため、
要素を追加・削除できないという大きな欠点がある。

②匿名クラスと初期化ブロックを使った方法

List<StringBuilder> list = new ArrayList<StringBuilder>() {
    {
        add(new StringBuilder("AAA"));
        add(new StringBuilder("BBB"));
    }
};

原理的にはすべてaddしている。

③ListのコンストラクタにListを与える

List<StringBuilder> list = new ArrayList<>(Arrays.asList(new StringBuilder("AA"), new StringBuilder("BB")));
要素の追加

①すべてaddする

②addAllを使う

List<StringBuilder> list = new ArrayList<>();
list.addAll(Arrays.asList(new StringBuilder("AA"), new StringBuilder("BB")));

③Collections.addAllを使う

List<StringBuilder> list = new ArrayList<StringBuilder>();
Collections.addAll(list, new StringBuilder("AA"), new StringBuilder("BB"));
配列とリストの相互変換

・配列からListに変換

List<StringBuilder> list = new ArrayList<StringBuilder>();
Collections.addAll(list, new StringBuilder("AA"),new StringBuilder("BB"));

・Listから配列に変換

List<StringBuilder> sb_list = new ArrayList<StringBuilder>() {
    {
        add(new StringBuilder("AA"));
        add(new StringBuilder("BB"));
    }
};
StringBuilder[] sb_array = sb_list.toArray(new StringBuilder[sb_list.size()]);

・軽いおさらい

StringBuilder[] sb_array = { new StringBuilder("AA"), new StringBuilder("BB") };
List<StringBuilder> sb_list = new ArrayList<>();
Collections.addAll(sb_list, sb_array);
sb_list.add(new StringBuilder("CC"));
for(StringBuilder sb : sb_list) {
    System.out.println(sb);
}

インターフェース

概要

インターフェースとはクラス同様オブジェクトの振る舞いの共通性を決めるもの。
しかし、クラスと違い雛型としての役割を持たなく、実体化できない。

インターフェースと抽象クラス

インターフェースは抽象クラスでもいいのではないか。
しかし抽象クラスは雛型としての役割もある。
次のように使い分ける。

クラスの拡張による継承は、実装の継承のために用いる
インターフェースの実装による継承は、振る舞いの継承のために用いる

指針としては
・変化しにくい振る舞いを規定して、それをインターフェースにまとめる
・クラスはインターフェースを継承することで、変化しにくい部分を表明する
・クラスではなくインターフェースに依存したコードにより、変化しにくい部分のみへの依存を保証する

インターフェースの修飾子

・public ... 書くとグローバル可視。書かないとパッケージ可視
・abstract ... インターフェースは暗黙にabstract。普通は書かない

インターフェースのメンバ

・抽象メソッド
・defaultメソッド
・staticメソッド
・定数フィールド
・staticなネストしたクラス
・staticなネストしたインターフェース

メソッド宣言

インターフェースのメソッド宣言の修飾子
・public ... 暗黙にpublicなので省略可
・default ... defaultメソッド
・static ... staticメソッド
・abstract ... 暗黙にabstractなので省略可

原則インターフェースに振る舞い以外の規定は持たせない
→できるだけインターフェースにstaticメソッドは実装しない

インターフェース定数

インターフェース内で宣言したフィールドをインターフェース定数という。
暗黙にpublic static finalである。

サンプルコード

interface Interface{
    int num = 1;
    String str = "AAA";
    void method();
}

class Sample implements Interface{
    @Override
    public void method() {
        System.out.println(num + str);
    }
}

class Sample2{
    void method() {
        System.out.println(Interface.str);
    }
}

正直インターフェースに関しては文法は覚えることは少ない。
使い方が大事になってくるであろう。
習うより慣れろの精神でいこうと思う。

関連記事

papyrustaro.hatenablog.jp

前回↑