質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

【至急】ラムダ式、StreamAPIについて

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,920
退会済みユーザー

退会済みユーザー

前提・実現したいこと

ラムダ式、StreamAPIを用いて以下の機能を実装したいと考えております。
・引数のリストから最大値の取得  
・引数のリストから特定の文字を表示させる  
・引数のリストから偶数のみを格納したリストを返す  
・引数のリストから重複している要素を
排除したハッシュセットを返す
・引数の年月日から半年前の年月日を返す

発生している問題

・引数のリストから最大値を取得させるところの
Optional<Integer> max = intLits.max(Comparator.naturalOrder());
のintLits.maxのmaxのところで
The method max(Comparator.naturalOrder()) is undefined for the type List<Integer>
というエラーが出てしまい対処法が不明

・特定の文字を抽出させる方法が不明
・偶数のみを格納したリストを
結果用のリストに格納させたいが
(i -> resultList.add(i));のところで
Multiple markers at this line

  • Syntax error, insert "AssignmentOperator Expression" to complete
    Expression
  • Syntax error, insert ")" to complete Expression
    というエラーが出てしまい対処に困っている

・引数の月から半年前の日付を表示させる方法(関数)が不明

追加事項:
forEachとstrListにおいて

  • Void methods cannot return a value
  • The method forEach(Consumer<? super String>) in the type Stream<String> is not
    applicable for the arguments ((<no type> str) -> {})
    というエラーが発生してしまいました。

// 引数の年月日から6ヵ月前の年月日を返すところで
LocalDateクラスのminusMonthsメソッドを使用してみたのですが
tring resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"))のところで
以下のエラーが発生してしまいました。  
Type mismatch: cannot convert from LocalDate to String

どちらもエラーの対処法と  
コードの訂正法を教えていただきたいです。  
なるべく早く実装させたいので宜しくお願いします。

該当のソースコード

public class Answer {
// 引数のリストから最大値を取得する
private Integer task1(List<Integer> intLits) {
//optionalクラス値を持てるクラス(nullCheckを省略(?))
//comparator=関数型のインターフェース(ここでは最大値取得を定義(?))
Optional<Integer> max = intLits.max(Comparator.naturalOrder());
return max.get();
}
// 引数のリストから重複している要素を除外したリストを返す
private List<String> task4(List<String> strList) {
List<String> resultList = new ArrayList<>();
strList.stream().distinct() // 要素をequalsで比較し、重複した要素を除く
.forEach(str -> strList); // 結果用リストに格納
// 引数のリストから「晴れ」のみを表示する
private void task2(List<String> strList) {
strList.stream().filter(str -> str) // リストの中から"晴れ"のみを抽出
.forEach(System.out::println); // 要素の出力
}
// 引数のリストから偶数のみを格納したリストを返す
private List<Integer> task3(List<Integer> intList) {
List<Integer> resultList = new ArrayList<>();
intList.stream().filter(i -> i % 2 == 0); // 要素を2で割って余りが0の要素を抽出
(i -> resultList.add(i)); // 結果用リストに格納
// 結果用のリストを返却する
return resultList;
}
// 引数のリストから重複している要素を除外したリストを返す
private List<String> task4(List<String> strList) {
List<String> resultList = new ArrayList<>();
strList.stream().distinct() // 要素をequalsで比較し、重複した要素を除く
.forEach(str -> strList); // 結果用リストに格納
// 結果用のリストを返却する
return resultList;
}
// 引数の年月日から6ヵ月前の年月日を返す(変更前)
private String task5(String strDate) {
String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 文字列から日付へ変換する
// 月から6を引く
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 引数の書式で文字列に再変換する
return resultDate;
}
/
// 引数の年月日から6ヵ月前の年月日を返す(変更後)  
private String task5(String strDate) {  
String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 文字列から日付へ変換する  
// 月から6を引く  
LocalDate.of(2016,06,26).minusMonths(-6)  
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 引数の書式で文字列に再変換する  
return resultDate;  
}  

//実行時のコード  

// strListの中から一意の要素を取り出す  
System.out.println(answer.task4(strList));  

// 6ヵ月前の年月日を表示する  
System.out.println(answer.task5("2016-06-26"));  

試したこと

参考書やサイトを見ながら自分なりに実装

補足情報(言語/FW/ツール等のバージョンなど)

使用言語:Java
使用ツール:STS
使用OS:Windows10

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+1

・引数のリストから最大値を取得させるところの 
Optional<Integer> max = intLits.max(Comparator.naturalOrder());

のintLits.maxのmaxのところで 
The method max(Comparator.naturalOrder()) is undefined for the type List<Integer> 
というエラーが出てしまい対処法が不明

ListをStreamに変換しないと、ご提示の操作はできません。

Optional<Integer> max = intLits.stream().max(Comparator.naturalOrder());

・特定の文字を抽出させる方法が不明 

strList.stream().filter(str -> str) // リストの中から"晴れ"のみを抽出 


ここでしょうか?filterの引数には条件に合うものにtrueを返すように設計すればいいので、

strList.stream().filter(str -> str.equals("晴れ")) // リストの中から"晴れ"のみを抽出 

・偶数のみを格納したリストを 
結果用のリストに格納させたいが 
(i -> resultList.add(i));のところで 
Multiple markers at this line

Syntax error, insert "AssignmentOperator Expression" to complete  
Expression
Syntax error, insert ")" to complete Expression 
というエラーが出てしまい対処に困っている

この直前でセミコロンにより文が切れています。前のStreamに続けて操作しないと意味をなしません。

intList.stream().filter(i -> i % 2 == 0) // 要素を2で割って余りが0の要素を抽出 
.forEach(i -> resultList.add(i)); // 結果用リストに格納


ただ、ここや他にもリスト化するのにArrayListを別途用意してStreamから取り出した要素を詰めるという手順を踏んでいるところがありますが、、Streamの要素をList化するのに便利なcollectメソッドがあります。

List<Integer> resultList = intList.stream().filter(i -> i % 2 == 0)
                                   .collect(Collectors.toList());

・引数の月から半年前の日付を表示させる方法(関数)が不明

LocalDateクラスのminusMonthsメソッドを使います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/26 05:40

    回答ありがとうございます。
    最大値の取得、特定の文字の表示、特定の数を格納したリストを返す実装については無事に解決いたしました。


    しかし

    // 引数のリストから重複している要素を除外したリストを返す
    private List<String> task4(List<String> strList) {
    List<String> resultList = new ArrayList<>();
    strList.stream().distinct() // 要素をequalsで比較し、重複した要素を除く
    .forEach(str -> strList); // 結果用リストに格納

    // 結果用のリストを返却する
    return resultList;
    }
    のforEachとstrListにおいて
    - Void methods cannot return a value
    - The method forEach(Consumer<? super String>) in the type Stream<String> is not
    applicable for the arguments ((<no type> str) -> {})

    というエラーが発生してしまっていること、さらに

    LocalDateクラスのminusMonthsメソッドを使用してみたのですが

    String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"))のところで
    以下のエラーが発生してしまいました。

    Type mismatch: cannot convert from LocalDate to String


    参考までに記入したソースコードを追記しますので訂正点を教えていただけると幸いです。


    ソースコード

    private String task5(String strDate) {
    String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 文字列から日付へ変換する
    // 月から6を引く
    LocalDate.of(2014,05,01).minusMonths(-6)
    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 引数の書式で文字列に再変換する
    return resultDate;
    }

    キャンセル

  • 2016/06/26 09:08

    どっちもコード化が中途半端です。
    前者は回答コードをよく見てください。私はforEachで何をしていますか?
    後者は、私はコードの流れ的にメソッドチェーンで書こうとしていると思ったのですが…
    parseの結果に続けてピリオドを打ち、minusMonthsを書きます。これに後のformatが続くようにします。
    あとminusMonthsに-6を渡すと結果が逆になりますよ。

    キャンセル

  • 2016/06/26 09:32

    無事に解決いたしました。
    懇切丁寧に教えていただきありがとうございました。

    また何か問題が発生した際には宜しくお願い致します。

    キャンセル

checkベストアンサー

0

swordoneさんの回答のコメントに対するレスです。

// 引数のリストから重複している要素を除外したリストを返す
private List<String> task4(List<String> strList) {
List<String> resultList = new ArrayList<>();
strList.stream().distinct() // 要素をequalsで比較し、重複した要素を除く
.forEach(str -> strList); // 結果用リストに格納
  // 結果用のリストを返却する
return resultList;
}
のforEachとstrListにおいて

  • Void methods cannot return a value
  • The method forEach(Consumer<? super String>) in the type Stream<String> is not 
    applicable for the arguments ((<no type> str) -> {})
      というエラーが発生してしまっていること

.forEachの中がおかしいです。
結果用リストに格納なのになぜ引数のstrListを指定してるのですか。
task3と同じ要領で下記のようにresultListを指定してください。

.forEach(str -> resultList.add(str)); // 結果用リストに格納

また、

LocalDateクラスのminusMonthsメソッドを使用してみたのですが

そのコメントしてくれたtask5メソッドも変です
strDateから引っ張ってるのにそこに直接LocalDate.of(2014,05,01)と入れてどうするの。
.(ピリオド)でつなげればいいんです。

// 引数の年月日から6ヵ月前の年月日を返す 
public String task5(String strDate) {
    String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 文字列から日付へ変換する
    // 月から6を引く(-6じゃないよ!!)
    .minusMonths(6)
    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 引数の書式で文字列に再変換する
    return resultDate;
}

あと見てみたら最初の質問を編集してますね。
レスがついた後なのに最初の質問を編集してしまうと、話の流れが分からなくなります。
やらない方が賢明ですよ。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/26 09:31

    無事に解決いたしました。
    懇切丁寧に教えていただきありがとうございました。

    また何か問題が発生した際には宜しくお願い致します。

    追伸:質問の編集についてですが
       始めたばかりで使用方法がわからない点がありますが以後気を付けます

    キャンセル

0

それぞれをテストクラスも含めて記載しましたのでご参考に。

import static org.junit.Assert.*;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.junit.Before;
import org.junit.Test;

/**
 * 
 * @author A-pZ
 */
public class StreamSampleTest {

    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void testMax() {
        List<Integer> integerList = Arrays.asList(1,2,4,8,16,320,64,128,256);

        Optional<Integer> max = integerList.stream().max(Comparator.comparingInt(i1 -> i1.intValue()));

        assertNotEquals(null, max.get());
        assertEquals(320L , (long)max.get());
    }

    @Test
    public void testWeather() {
        List<String> weather = Arrays.asList("雨","晴れ","くもり","快晴","大雨");

        Optional<String> result = weather.stream().filter(w -> w.equals("晴れ")).findAny();

        assertNotEquals(null,result.get());
        assertEquals("晴れ",result.get());
    }

    public void testEven() {
        List<Integer> numberList = Arrays.asList(1,3,5,7,9,0,2,4,6,8,13,35,72,100);

        List<Integer> evenList = numberList.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());

        assertTrue(evenList.contains(0));
        assertTrue(evenList.contains(2));
        assertTrue(evenList.contains(4));
        assertTrue(evenList.contains(6));
        assertTrue(evenList.contains(8));
        assertTrue(evenList.contains(72));
        assertTrue(evenList.contains(100));
        assertFalse(evenList.contains(1));
        assertFalse(evenList.contains(3));
        assertFalse(evenList.contains(5));
        assertFalse(evenList.contains(7));
        assertFalse(evenList.contains(9));
        assertFalse(evenList.contains(13));
        assertFalse(evenList.contains(35));
    }

    @Test
    public void testDistinct() {
        List<String> duplicate = Arrays.asList("雨","晴れ","くもり","晴れ","晴れ","雨");

        List<String> result = duplicate.stream().distinct().collect(Collectors.toList());

        assertEquals(1, result.stream().filter(d -> d.equals("晴れ")).count());
        assertEquals(1, result.stream().filter(d -> d.equals("雨")).count());
        assertEquals(1, result.stream().filter(d -> d.equals("くもり")).count());
        assertEquals(0, result.stream().filter(d -> d.equals("曇り")).count());
    }

    @Test
    public void before6Month() {
        LocalDate ldate = LocalDate.of(2016, 8, 8);
        LocalDate check = ldate.minusMonths(6);

        assertEquals(2016 , check.getYear());
        assertEquals(2 , check.getMonthValue());
        assertEquals(8 , check.getDayOfMonth());
    }

    @Test
    public void before6MonthOverYeae() {
        LocalDate ldate = LocalDate.of(2016, 3, 25);
        LocalDate check = ldate.minusMonths(6);

        assertEquals(2015 , check.getYear());
        assertEquals(9 , check.getMonthValue());
        assertEquals(25 , check.getDayOfMonth());
    }

}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/26 09:05

    回答ありがとうございます。
    最大値の取得、特定の文字の表示、特定の数を格納したリストを返す実装については無事に解決いたしました。


    しかし

    // 引数のリストから重複している要素を除外したリストを返す
    private List<String> task4(List<String> strList) {
    List<String> resultList = new ArrayList<>();
    strList.stream().distinct() // 要素をequalsで比較し、重複した要素を除く
    .forEach(str -> strList); // 結果用リストに格納

    // 結果用のリストを返却する
    return resultList;
    }
    のforEachとstrListにおいて
    - Void methods cannot return a value
    - The method forEach(Consumer<? super String>) in the type Stream<String> is not
    applicable for the arguments ((<no type> str) -> {})

    というエラーが発生してしまっていること、さらに

    LocalDateクラスのminusMonthsメソッドを使用してみたのですが

    String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"))のところで
    以下のエラーが発生してしまいました。

    Type mismatch: cannot convert from LocalDate to String


    参考までに記入したソースコードを追記しますので訂正点を教えていただけると幸いです。


    ソースコード

    private String task5(String strDate) {
    String resultDate = LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 文字列から日付へ変換する
    // 月から6を引く
    LocalDate.of(2014,05,01).minusMonths(-6)
    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 引数の書式で文字列に再変換する
    return resultDate;
    }

    キャンセル

  • 2016/06/26 09:32

    無事に解決いたしました。
    懇切丁寧に教えていただきありがとうございました。

    また何か問題が発生した際には宜しくお願い致します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る