-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の仕様で、ラムダ式内では、ラムダ式外の変数に対して、次のことができない。
- プリミティブ型の値を変更する
- 参照型の参照先を変更する
したがって、次の例は失敗する。(コンパイルエラー)
static double[] vectors_add(double[] vector1, double[] vector2)
{
/*final*/ int index = 0;
return Stream.of(vector1).map(v1 -> v1 + vector2[index++]).toArray();
}
要は、ラムダ式内で使いたい変数を外で定義すると、final変数同然になってしまうということ。
そこで、「プリミティブ型の配列という参照型」を使い、中身を変更するという手法をとった。
そうすれば、中身をいくら更新しようとも、参照先を変更していないので怒られない。
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()); //福田 早苗 福田 松男 福田 太郎
}