0
0

More than 3 years have passed since last update.

javaのstreamとかラムダ式とかFunctionとか配列とかListやMapとかをこれから実践していくつもりです

Last updated at Posted at 2020-03-17

-1.お断り

勉強中の身ながら執筆しております。
下書きが10個たまってしまってこれ以上下書きが増やせないので、全然内容がないけどもう公開しちゃいます。
ここに乗っているのが最適とは限りません。
コメント等いただければ嬉しい限りです。

また、各メソッドについて、所属するクラス名はTestとします。
また、import java.util.Arrays;, import java.util.Stream;をしてください。

0. List⇔配列

0-1. List<Hoge> → Hoge[]

    static class Hoge{String s;Hoge(String s_){s=s_;}String f(){return s;}}

    static Test.Hoge[] hoge_list_to_array(List<Test.Hoge> hoge_list)
    {
        //return (Hoge[]) hoge_list.toArray(); ←ダメな例
        return hoge_list.toArray(Test.Hoge[]::new);
    }

    public static void main(String...args)
    {
        ArrayList<Test.Hoge> hoge_list = new ArrayList<>(Arrays.asList(new Test.Hoge[]{new Hoge("hoge1"), new Hoge("hoge2")}));

        System.out.println(Test.hoge_list_to_array(hoge_list).getClass().getName());//[Ltrash.Test$Hoge;
        Stream.of(Test.hoge_list_to_array(hoge_list)).forEach(hoge -> System.out.println(hoge.f()));//hoge1 hoge2
    }

0-2. Hoge[] → List<Hoge>

    static ArrayList<Test.Hoge> hoge_array_to_list(Test.Hoge[] hoge_array)
    {
        //return (ArrayList<Hoge>) Arrays.asList(hoge_array); ←ダメな例
        return new ArrayList<Hoge>(Arrays.asList(hoge_array));
    }

    public static void main(String...args)
    {
        Test.Hoge[] hoge_array = new Test.Hoge[]{new Hoge("hoge1"), new Hoge("hoge2")};

        System.out.println(Test.hoge_array_to_list(hoge_array).getClass().getName());
        for(Test.Hoge hoge : Test.hoge_array_to_list(hoge_array))//java.util.ArrayList (型パラメータ情報は消える)
            System.out.println(hoge.f());//hoge1 hoge2
    }

1.数学的計算

1-1. 線形数学(ベクトル、行列、テンソル等)

double等のn次元配列を階数nのテンソルとみなします。
つまりベクトルといったらdouble[],行列といったらdouble[][]をイメージしてほしいわけです。

1-1-1. ベクトルの絶対値を求める

static double abs(double[] vector)
{
    return Math.sqrt(Stream.of(vector).map(comp -> comp*comp).sum());
}


public static void main(String...args)
{
    double[] vector = {3,4};
    System.out.println(Test.abs(vector));//5.0
}

1-1-2. ベクトルに成分を追加

例えば $\left( \begin{array}{} 1 \\ 2\end{array} \right)$ に3を追加して$\left( \begin{array}{} 1 \\ 2 \\ 3 \end{array} \right)$ とするなど。

    static double[] add_comp(double[] vector, double comp)
    {
        return Stream.concat(Stream.of(vector).boxed(), Stream.of(new Double[]{comp})).mapToDouble(d->d).toArray();
    }

    public static void main(String...args)
    {
        double[] vector = {1,2};
        double comp_to_add = 3;
        vector = Test.add_comp(vector, comp_to_add);
        for(double comp : vector)System.out.println(comp);// 1.0 2.0 3.0
    }

return Arrays.asList(vector, comp).toArray(double[]::new);はコンパイル時に怒られる。
return (double[])(Object)Arrays.asList(vector, comp).toArray();は実行時にClassCastExceptionとなる。
Stream.concatメソッドはプリミティブのStreamに対しては使えない。そのため一度ラップしてから、mapToDouble(d->d)でアンラップ。

1-1-3. ベクトルの加算

    static double[] vectors_add(double[] vector1, double[] vector2)
    {
        final int[] inde = {0}; final int x = 0; 
        return Stream.of(vector1).map(v1 ->  v1 + vector2[inde[x]++]).toArray();
    }

    public static void main(String...args)
    {
        double[] ds1 =  {1,2,3};
        double[] ds2 =  {4,5,6};

        for(double comp : Test.vectors_add(ds1,ds2))
            System.out.println(comp);//5.0 7.0 9.0
    }

javaの仕様で、ラムダ式内では、ラムダ式外の変数に対して、次のことができない。

  • プリミティブ型の値を変更する
  • 参照型の参照先を変更する

したがって、次の例は失敗する。(コンパイルエラー)

🚫ラムダ式外のプリミティブ型変数indexをラムダ式内で変更しようとしたのでエラーになる例
    static double[] vectors_add(double[] vector1, double[] vector2)
    {
        /*final*/ int index = 0;
        return Stream.of(vector1).map(v1 ->  v1 + vector2[index++]).toArray();
    }

要は、ラムダ式内で使いたい変数を外で定義すると、final変数同然になってしまうということ。

そこで、「プリミティブ型の配列という参照型」を使い、中身を変更するという手法をとった。
そうすれば、中身をいくら更新しようとも、参照先を変更していないので怒られない。

これならOK
    static double[] vectors_add(double[] vector1, double[] vector2)
    {
        final int[] inde = {0}; final int x = 0;
        return Stream.of(vector1).map(v1 ->  v1 + vector2[inde[x]++]).toArray();
    }

2.文字列関連

2-1.正規表現関連

2-1-1. 正規表現にマッチする「名前」を持つオブジェクトをArrayListから〇〇する

例えばPersonクラスがメソッドとしてString get_name()メソッドを持っているとする。
そしてこの戻り値を、Person型インスタンスの「名前」と呼ぶことにする。

2-1-1-1. 取得する

    static class Person
    {
        private String name;
        Person(String name){this.name = name;}
        String get_name(){return this.name;}
    }

    static java.util.List<Test.Person> get_person_by_name_regex(java.util.List<Test.Person> list, String regex)
    {
        java.util.List<Test.Person> list_tmp = new ArrayList<>(list); //ディープコピー
        list_tmp.removeIf(person -> !person.get_name().matches(regex));
        return list_tmp;
    }

    public static void main(String...args)
    {
        Person[] sanaesan_members =
        {
            new Test.Person("福田 早苗"), //福田家 妻
            new Test.Person("福田 松男"), //〃夫
            new Test.Person("福田 太郎"), //〃長男
            new Test.Person("磯野 網平"), //磯野家 夫
            new Test.Person("磯野 久根"), //磯野家 妻
            new Test.Person("磯野 和夫"), //磯野家長男
            new Test.Person("磯野 若菜"), //磯野家次女
            new Test.Person("磯野 玉")//磯野・福田家愛猫
        };
        java.util.List<Test.Person> list = new ArrayList<>(Arrays.asList(sanaesan_members));

        for(Test.Person isono : Test.get_person_by_name_regex(list, "^磯野.*$"))
            System.out.println(isono.get_name()); //磯野 網平  磯野 久根  磯野 和夫  磯野 若菜  磯野 玉

    }

2-1-1-2. 消去する

    static class Person
    {
        private String name;
        Person(String name){this.name = name;}
        String get_name(){return this.name;}
    }

    static void remove_person_by_name_regex(java.util.List<Test.Person> list, String regex)
    {
        list.removeIf(person -> person.get_name().matches(regex));
    }

    public static void main(String...args)
    {
        Person[] sanaesan_members =
        {
            new Test.Person("福田 早苗"), //福田家 妻
            new Test.Person("福田 松男"), //〃夫
            new Test.Person("福田 太郎"), //〃長男
            new Test.Person("磯野 網平"), //磯野家 夫
            new Test.Person("磯野 久根"), //磯野家 妻
            new Test.Person("磯野 和夫"), //磯野家長男
            new Test.Person("磯野 若菜"), //磯野家次女
            new Test.Person("磯野 玉")//磯野・福田家愛猫
        };
        java.util.List<Test.Person> list = new ArrayList<>(Arrays.asList(sanaesan_members));
        Test.remove_person_by_name_regex(list, "^磯野.*$");

        for(Test.Person hukuda : list)
            System.out.println(isono.get_name()); //福田 早苗  福田 松男  福田 太郎

    }
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0