1. 要素 3 つの配列の長さは 3
  2. 空配列の長さは 0
  3. 要素 1 つの配列の長さは 1
  4. 要素 5 つの配列の長さは 5
コース一覧
Java 中級:コレクション・Stream・例外処理
ワイルドカード ?

Java 中級:コレクション・Stream・例外処理

コレクション、ジェネリクス、例外処理、Stream API、関数型インターフェース、日付処理、ファイル I/O、継承など Java の中級トピックを実践的に学べるコースです。Java の基礎文法とオブジェクト指向を理解している学習者を対象に、現場の Java コードを読み書きするための知識を補強します。約 16 時間 (1 日 30 分 × 32 日) で 64 レッスンを修了でき、修了後は Spring Boot や業務システム開発に必要な Java 力が身につきます。

1
コレクション基礎
01. ArrayList を使う5分
02. List を走査する5分
03. 要素の削除と検索5分
04. HashMap の基本5分
05. Map を走査する5分
06. Set で重複を排除5分
07. Collections クラスの便利メソッド5分
08. コレクション基礎 まとめクイズ5分
2
ジェネリクス
01. ジェネリッククラスを作る5分
02. ジェネリックメソッド5分
03. 境界型パラメータ5分
04. ワイルドカード ?5分
05. Pair<K,V> を作る5分
06. ジェネリクス まとめクイズ5分
3
例外処理
01. try-catch で例外をつかむ5分
02. 複数の catch ブロック5分
03. throws と例外の伝播5分
04. 独自の例外を作る5分
05. try-with-resources5分
06. finally ブロック5分
07. 例外処理 まとめクイズ5分
4
Stream API
01. Stream を作る5分
02. filter で絞り込む5分
03. map で変換する5分
04. reduce で集約する5分
05. collect で集める5分
06. sorted で並び替え5分
07. distinct で重複排除5分
08. limit と skip5分
09. 並列ストリーム5分
10. Stream API まとめクイズ5分
5
関数型インターフェース
01. ラムダ式の基本5分
02. メソッド参照 ::5分
03. Function インターフェース5分
04. Predicate インターフェース5分
05. Consumer と Supplier5分
06. BiFunction と 2 引数の関数5分
07. 関数型インターフェース まとめクイズ5分
6
文字列操作
01. String.format で書式化5分
02. StringBuilder で連結5分
03. 正規表現の基本5分
04. split と join5分
05. 文字列操作 まとめクイズ5分
7
日付と時刻
01. LocalDate で日付を扱う5分
02. LocalDateTime で時刻も扱う5分
03. Duration で時間差を計算5分
04. 日付の書式化とパース5分
05. 日付の加減算5分
06. 日付と時刻 まとめクイズ5分
8
ファイル I/O
01. Files でファイルに書き込む5分
02. ファイルを行単位で読む5分
03. Path でファイルパスを扱う5分
04. BufferedReader と Stream API5分
05. ファイルの存在確認と削除5分
06. ファイル I/O まとめクイズ5分
9
継承とポリモーフィズム
01. extends で継承する5分
02. super で親を呼ぶ5分
03. メソッドのオーバーライド5分
04. abstract で抽象クラス5分
05. interface で契約を定義5分
06. default メソッド5分
07. instanceof と型パターン5分
08. ポリモーフィズムを活かす5分
09. 継承とポリモーフィズム まとめクイズ5分

ワイルドカード ?

型が違うだけの同じメソッドを 3 本書くのはつらい

「リストの件数を数えたいだけ」なのに、List<Integer> 用と List<String> 用と List<Double> 用を別々に書く。ジェネリクスを覚えた直後に必ず一度はぶつかる場面です。List<String> を List<Object> の引数に渡すことすらできません。String は Object のサブクラスでも、List<String> は List<Object> のサブクラスにはならない、という決まりがあるからです。

そこで使うのが ? (ワイルドカード) です。List<?> は「中身の型は分からないが、とにかくリスト」を表します。

Java

public static void printSize(List<?> list) { System.out.println("件数は " + list.size()); }

size() は中身の型に関係なく int を返すので、これ 1 本で List<Integer> も List<String> も受けられます。件数を数えるだけなら、中身の型の情報は最初から要らなかったわけです。

取り出した値が Object になって、足せない

素の ? には弱点があります。取り出した要素が Object 扱いになるので、Number のメソッドが呼べません。「数値のリストを受け取って平均を出す」のような処理が書けないのです。

ここで ? extends Number と書くと、「Number かそのサブクラス」まで型が絞られます。

Java

public static double averageOf(List<? extends Number> list) { double total = 0.0; for (Number n : list) { total += n.doubleValue(); } return total / list.size(); }

List<Integer> も List<Double> も渡せて、中では Number として読めます。ただし list.add(1) は書けません。呼び出し側が渡したのが List<Integer> なのか List<Double> なのかコンパイラには分からないので、安全に入れられる型が決まらないからです。

今度は add が通らない

逆に「リストへ値を入れる側」を書きたいときは ? super Integer を使います。「Integer かその親」という意味で、List<Integer> List<Number> List<Object> のどれを渡されても、Integer を入れるぶんには安全です。

Java

public static void fillWithZeros(List<? super Integer> list, int count) { for (int i = 0; i < count; i++) { list.add(0); } }

こちらは書き込みができる代わりに、取り出した値は Object までしか保証されません。

判断は「そのリストから読むだけか、そこへ入れるか」の一点です。読むだけなら ? extends、入れるなら ? super。読み書き両方するなら、ワイルドカードをやめて List<Integer> のような具体型で受けます。

解説

覚え方 Producer Extends, Consumer Super の頭文字を取って PECS と呼ばれます。語呂を思い出すより「読む側か、書く側か」で判断するほうが早いです。

よくある間違い

いちばん多いのは List<?> に add しようとして capture of ? というエラーで止まるパターンです。List<?> に安全に入れられるのは null だけなので、入れたいときは ? super にするか、具体型に戻してください。

もう 1 つ、戻り値の型に ? を使うのも避けてください。List<?> load() のようなメソッドは、呼び出し側が要素を取り出すたびに Object 扱いになって、結局キャストだらけになります。

要件

  1. Solution.countItems(int[] arr) メソッドを実装し、配列の要素数を int で返すこと
  2. arr.length を使って要素数を取得すること (ループでカウントする必要はない)
  3. 戻り値の型は int、引数の型は int[] のシグネチャを変えないこと

入出力例

countItems([1,2,3]) → 3 countItems([]) → 0 countItems([5]) → 1 countItems([10,20,30,40,50]) → 5

ヒント

配列の要素数は `arr.length` で取得できます。`()` を付けて `arr.length()` と書くとメソッド呼び出し扱いになりエラーになるので注意してください

本文の `List<?>` 版で言うところの `list.size()` に相当します。`size()` と `length` は名前が違うだけで意味は同じです

空配列でも `null` ではないので `arr.length` は `0` を返します。`null` チェックは今回の課題では不要です

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • Pair<K,V> を作る

    複数の型パラメータを持つジェネリッククラス Pair<K,V> を題材に、HashMap<K,V> と同じ仕組みでキーと値の組を表現する方法と、Record を使った最新の書き方を学ぼう。

  • ジェネリクス まとめクイズ

    ジェネリッククラス / ジェネリックメソッド / 境界型 / ワイルドカード / Pair の総まとめ。PECS や型消去 (type erasure) など実務で問われやすい論点を 4 択クイズで確認する。

  • try-catch で例外をつかむ

    Java の例外処理の基本となる try-catch 構文を学び、NumberFormatException を捕まえてデフォルト値を返すコードを書いてみよう。

  • Stream を作る

    Java の Stream API を学ぶ最初のステップとして、配列やコレクションから Stream を生成し、count などのターミナル操作で要素数を取得するコードを書いてみよう。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • メソッドクラスに属する関数
  • リスト順序付きで複数の値を扱うデータ構造
  • ジェネリクス<String> のように型を指定する仕組み
  • 引数位置引数=順番で渡す。
  • クラスデータと振る舞いを束ねる単位
  • 処理計算や代入を表す長方形
  • 判断YES/NO 分岐を表す菱形
  • 戻り値呼び出し元への返答を表す点線矢印
main.java
学習モード
エディタを読み込んでいます

メモ

ワイルドカード ?

⌘S で保存