エンジニアの知恵袋

エンジニアの知恵袋

フリーランスシステムエンジニアをしています。日々感じたことや学んだことをアウトプットしていきます。

Java SteramAPIの中間操作

JavaのSteramAPI中間操作(処理)に関してまとめていきます。 各Collection系のSteramAPI操作に関してはこちらの記事に掲載済み。

engineer-wisdom.hatenablog.jp

目次

  1. 中間操作とは
  2. filter処理
  3. map処理
  4. sorted処理
  5. limit処理

中間操作とは

中間操作(処理)とはStreamAPIにおいて、各Collection系のオブジェクトをSteramで流した時に様々な編集、抽出を行う操作です。 例えばListの中から特定の文字が入るもので絞る操作を行ったり、要素の変更を行ったり、ソート処理を行ったりできます。 SteramAPIの肝となる部分と言っても良いと思うので、使用頻度の高そうなものをここにまとめておきたいと思います。

filter処理

filter処理では要素を特定の条件に沿って絞ることができます。

// List型
List<String> animalList = Arrays.asList("Dog","Cat");
// Filter処理
animalList.stream().filter(a -> a.startsWith("D"))
        .forEach(System.out::println);

■実行結果

Dog

上記のコードではは宣言したListの中からfilter内で「Dで始まるもの」という条件で真になるものを絞った結果が出力されます。

map処理

map処理では要素を指定した値に変化させることができます。

List<String> animalList = Arrays.asList("Dog","Cat");
// Map処理
animalList.stream().map(a -> a.toUpperCase())
    .forEach(System.out::println);

■実行結果

DOG
CAT

上記のコードではmap内でアルファベットを大文字にする処理を行っています。
また、map処理では主にオブジェクト内の特定のフィールドを抽出するケースが多いので、そちらの例も載せておきます。

@AllArgsConstructor
@Data
public class Animal {
    String name;
    String type;
}

List<Animal> animalList = Arrays.asList(
        new Animal("Poti","Dog"),
        new Animal("Tama","Cat")
    );
// Map処理
animalList.stream().map(a -> a.getName())
        .forEach(System.out::println);

■実行結果

Poti
Tama

上記のようにすればObjectから特定のフィールドのみを取り出すことが出来ます。

sorted処理

sorted処理では要素をソートすることができます。

List<String> animalList = Arrays.asList("Dog","Cat");
// Sort処理
animalList.stream().sorted().forEach(System.out::println);

■実行結果

Cat
Dog

sort処理ではオブジェクトの特定のキーを使用してソートを実行するケースが多いため、そちらも覚えておきましょう。

@AllArgsConstructor
@Data
public class Animal {
    String name;
    String type;
}
List<Animal> animalList = Arrays.asList(
    new Animal("Poti","Dog"),
    new Animal("Tama","Cat"),
    new Animal("Mike","Cat")
);
// 第一ソートキーtype、第二ソートキーnameで昇順ソートする
animalList.stream().sorted(Comparator.comparing(Animal::getType)
        .thenComparing(Comparator.comparing(Animal::getName)))
        .forEach(System.out::println);

■実行結果

StreamApiTest.Animal(name=Mike, type=Cat)
StreamApiTest.Animal(name=Tama, type=Cat)
StreamApiTest.Animal(name=Poti, type=Dog)

上記のコードはComparetor.comparingを使用して、第一ソートキーをAnimalクラスのtypeフィールドとし、 thenComparingを使用して第二ソートキーをnameフィールドとしています。

もし降順ソートを行う場合は.reversed()を付けてください。

// 第一ソートキーtypeの昇順、第二ソートキーnameで降順ソートする
animalList.stream().sorted(Comparator.comparing(Animal::getType)
        .thenComparing(Comparator.comparing(Animal::getName).reversed())
        .forEach(System.out::println);

■実行結果

StreamApiTest.Animal(name=Tama, type=Cat)
StreamApiTest.Animal(name=Mike, type=Cat)
StreamApiTest.Animal(name=Poti, type=Dog)

limit処理

limit処理では要素を指定した数で打ち切ることができます。
sort処理と組み合わせると特定の要素でソートした後に要素を絞ることが可能です。

@AllArgsConstructor
@Data
public class Animal {
    String name;
    String type;
}
List<Animal> animalList = Arrays.asList(
    new Animal("Poti","Dog"),
    new Animal("Tama","Cat"),
    new Animal("Mike","Cat")
);
animalList.stream().sorted(Comparator.comparing(Animal::getType))
        .limit(2).forEach(System.out::println);

■実行結果

StreamApiTest.Animal(name=Tama, type=Cat)
StreamApiTest.Animal(name=Mike, type=Cat)

limit内には整数を入力します。
上記コードでソートした結果から上位2件が取得されたことがわかります。

中間操作を一つずつ使って覚えていく

StreanAPI従来のレガシーなJavaの書き方とは少し異なったものになるので、初めはパッと記述するのは難しいかもしれません。
最初の頃は当サイトを始め参考サイトを見ながら実際に作ってみながら徐々に覚えていくのが良いんじゃないでしょうか。
次回は終端操作に関してまとめていきます。

Java StreamAPI

Java8から使えるようになったSteramAPIですが、配列やList、Map型の変数を扱う時に大変便利なものですよね。
しかし、書き方に若干クセがあり私もしょっちゅう忘れます。 その都度調べながらという感じなので自分のブログにも残しておきたいと思います。

一個の記事に全ては書ききれないので、今回は各種配列、LIst、Mapを扱う時のSteramAPIの書き方についてまとめておきます。

配列の時のSteramAPI

配列の場合はjava.util.ArraysにstreamAPIが用意されているのでそちらを使用。

// 配列型定義
String[] animalArray = {"Dog","Cat"};
// SteramAPIでCから始まるものに絞る
Arrays.stream(animalArray).filter(a -> a.startsWith("C"))
            .forEach(System.out::println);

■実行結果

Cat

List型の時のSteramAPI

List型の場合はjava.util.ArrayListにstreamAPIが用意されているので、List型で宣言された変数から使用可能。

// List型
List<String> animalList = Arrays.asList("Dog","Cat");
// SteramAPIでCから始まるものに絞る
animalList.stream().filter(a -> a.startsWith("C"))
            .forEach(System.out::println);

Map型の時のSteramAPI

Map型の場合はjava.util.Map自体にはstreamAPIが用意されていないため、entrySetを経由して使用する。

// Map型
Map<Integer,String> animalMap = 
                new HashMap<Integer,String>()
                {{put(1,"Dog");put(2, "Cat");}}; 
// SteramAPIでCから始まるものに絞る
animalMap.entrySet().stream()
            .filter(a -> a.getValue().startsWith("C"))
            .forEach(System.out::println);

StreamAPIの各型に対する記述方法をまとめました

とりあえず今回はStreamAPIを使用するときに各型での書き方をまとめてみました。 多分また忘れると思うのでちょくちょくここで見直そうかと思います。 StreamAPIの中間処理に関してはまた今度の機会に書きます。

正規表現

最近正規表現を扱うことがあったのでメモ書き。
基本的なものは身についているのですが、ちょっと難しくなると思い出せなくなるのでここに残しておこうかと。

目次

  1. 正規表現におけるメタ文字
  2. [...]いずれかの文字パターン
  3. (...)グルーピング
  4. (?=...)、(?<=...)後読み、先読み

正規表現におけるメタ文字

基本的なことですが、メタ文字とは正規表現において「」、「?」、「.」、「$」など特別な意味を持つ文字のこと。
例えば「メタ
文字」という文字列があった時にこれは「メタ文字」という検索ワードで検索してもヒットしない。
」が「前の文字の繰り返し」という意味を持つからです。
メタ文字に含まれる文字を検索する場合はエスケープをしてあげる必要があります。
「メタ*文字」という具合に。ただし、いずれかの文字を検索する[・・・]には普通の文字として認識されるのを注意しておきたいですね。

[...]いずれかの文字パターン

検索文字を「[]」で括ると中のいずれかの文字にヒットするという検索になる。
グルーピングの「()」と間違えやすいので注意したいですね。

[ABC]であればAかBかCのいずれかがあればヒットする。
ここで良く使うのはアルファベットかどうか、数字かどうかなどでしょうか。

例:アルファベットをヒットさせたい時
[A-Za-z]

大文字と小文字を両方ヒットさせたい場合。片方であれば大文字や小文字だけ書けばOK。

例:数字をヒットさせたい時
[0-9]もしくは[\d]

[\d]の方がスマートで好きです。

逆に~以外と否定の意味を持たせたい時は[^A-Z]と付ければ良い。

(...)グルーピング

「()」で括った文字の塊が含まれているかで検索してくれる。

例:ABCという文字列のグループで検索したい時 (ABC)

ただこれだと普通に「ABC」と検索し時と変わらなくね?と思った方もいるかもしれないです。
はい、このパターンだと変わらないです。
グルーピングが力を発揮するのはメタ文字と組み合わせです。

例:西暦もしくは和暦での年をヒットさせたい時(和暦名は仮で英数字以外とする)
(\d{4}|[^\w]{2}\d{1,2})年

{n}は直前のパターンの繰り返しなので、数字4桁か○○n年をヒットさせるようにしています。
一番使用するのはOR条件を表す「|」かなと思います。

(?=...)、(?<=...)後読み、先読み

始めはこれ全然理解できなかったんですが、ようは「検索条件としては入れたいけど、ヒットする文字には含めたくない」というケースで使用するようです。
後に~がついている、先に~がついている○○○を検索したいというような形で使います。

例:後にDEFがついているABCを検索したい時
ABC(?=DEF)

この時「ABCDEFGABC」という文字列があった場合、ヒットするのは初めの「ABC」だけになります。
否定の場合は(?!)とつける。

例:先にEFGがついているABCを検索したい時
(?<=EFG)ABC

この時「ABCDEFGABC」という文字列があった場合、ヒットするのは最後の「ABC」だけになります。
否定の場合は(?<!)とつける。

この後読み、先読みはよくHTMLタグ内の文字をヒットさせる時などに使われますね。

例:h1タグ内のテキストを取得したい時

(?<=<h1>).*(?=</h1>)

<h1\>h1のテキストだよ</h1>というケースの場合「h1のテキストだよ」が抜き出されます。

正規表現との戦いは続く

ここに書いたことはごくごく少数のパターンでしかありません。
自分自身が忘れそうなやつだけ書いておきましたが、私もよく分からなくなるのでやっぱり調べながら作っています。
正規表現で調べると沢山まとめてくださっているサイトがありますので分からなくなった時はぜひ皆さんも調べてみてください。

なお、作った正規表現が合っているかを確認するのによく以下のサイトを使用させて頂いています。

www-creators.com

よろしければご参照ください。

Markdown(マークダウン)記法

Markdown(マークダウン)記法とは

Markdown(以下マークダウン)記法とはwikiやプロジェクト管理ツールなどにおいてテキストの文章を書くときに簡単に見出し、箇条書き、フォントなどを装飾できる記述方法ですね。 お恥ずかしいことに今のプロジェクト入るまでは私は知りませんでした。 このブログもマークダウン記法を使用して記載しています。

エクセルやワードみたいにいちいち文字やセルを選択して装飾しなくて良いので便利ですよね。 Redmineだったり、Backlogだったりのプロジェクト管理ツールや、AWSなどでも使用されているようで、用途はかなり多そうなので覚えておいて損はなさそうです。

私も忘れがちなのでここにまとめておきたいと思います。

マークダウンの主な種類

私が主に使用頻度が高いマークダウン記法のルールを列挙します。

記号 意味
**テキスト** 太字
~~テキスト~~ 取り消し線
# テキスト 見出し。行頭に付ける。
#の数を増やすごとに見出しレベルが下がる
* テキスト 箇条書き。行頭に付ける。
スペースを4つ開けるごとに
インデントを下げられる
1. テキスト 番号付きの箇条書き。
数字はカウントアップする必要がない。
> テキスト 引用
`テキスト` インライン。テキストこんな感じで単語が
コピーしやすくなる
```
テキスト
```
コードブロック。ソースコードなど
貼るときにとても便利
[テキスト](リンク
もしくはアンカー)
リンク。一つ目の見出しへ
|ヘッダー1|ヘッダー2|
|--|--|
|テキスト|テキスト|
テーブル。結構忘れやすい。
「--」の前後に「:」を付けると
文字位置調整できる

ざっとこの辺りを覚えておけばやって行けるかと思います。 積極的に色々使いながら覚えていきましょうか。

はじめに

はじめまして。 フリーランスシステムエンジニアをしております。

10年程度の会社勤めを経験した後、更に技術スキルを磨きたい思いから独立後現在はWebエンジニアとして働いています。 日々新しいことを学びながら楽しく働いております。

このブログは自分自身の日頃の思いや学んだことをアウトプットする場所がほしいと思い、立ち上げました。 ナレッジだったり、メモ書きだったり、頭の整理をするのに活用出来れば良いなと思います。

雑多な内容になってしまうかもしれませんが、日々気づいたことなどを発信していければと思っております。 今後ともよろしくお願いします!