ユーザーの選択/入力に基づいて、コレクションからオブジェクトをフィルタリング

DrAhzek:

私はむしろ簡単なエクササイズを持っているが、私は私の知識と使用デザインパターンへの要求事項(+ユニットテスト)によって制限されています。プロジェクトの目標は、コレクションからの印刷(すべて表示する)、削除(cryteriaでは除去)とフィルタ(基準によってショー)のメッセージをあなたが(アドオン)を保存することができますコンソールアプリケーションを作成することです。

private String title;
private String author;
private String content;
private String creationDate;

私は「すべてを表示」「アドオン」関数を作成し、することができました。私の問題は、フィルタリングです。私は、ユーザー(:タイトルとのCreationDateなどのタイトルによってフィルタによるフィルタのようにすべての可能な組み合わせ)によって与えられた基準に基づいてオブジェクトを保存したフィルタにオプションを作成する必要があります。私は、ユーザーにこのようなスイッチとメソッドを使用して、メニューからそれを選択するオプションを与えることについて考えました:

private final List<Message> storage = new ArrayList<Message>();

public List<Message> getAll() {
    final ArrayList<Message> messages = new ArrayList<>();
    messages.addAll(storage);
    return messages;
}
List<Message> find(String author) {
    return simpleStorage.getAll().stream()
        .filter(item -> item.getAuthor() == author)
        .collect(toList());
}

私はそれが類似したコードの多くをコピーすることをお勧めではないと思います。また、私はこのようなソリューションは、(それぞれの新しいパラメータは、新しい組み合わせを追加します)退屈とさえ不可能であろうと、将来的に自分自身を見つけるかもしれません。それを行うには良い方法はありますか?ユーザーが自分で組み合わせを作成することができますので、基準「一つずつ」を選択するような?私は、述語はこれで私を助けることができるが、私はここで行くことに知らないことをヒントを持っていました。

アンドリューTobilko:

各基準について、あなたが持っている可能性がBiPredicate<String, Message>1ユーザーとメッセージからの生の入力を受け取り、およびメッセージがフィルタリングオプション一致した場合に通知します2

Map<String, BiPredicate<String, Message>> criteria = Map.of(
        "title", (userTitle, message) -> input.equals(message.getTitle())
        ...
);

私はあなたにそのマップを使用することができる方法の簡単な例をあげます:

Scanner scanner = new Scanner(System.in);

String filteringOption = scanner.nextLine();
String userInput = scanner.nextLine();

BiPredicate<String, Message> predicate = criteria.get(filteringOption);

// get all messages from the storage
getAll()  
        // make a stream out of them
        .stream()
        // apply the filtering rule from the map
        .filter(m -> predicate.test(userInput, m))  
         // collect them into a list to display
        .collect(Collectors.toList());

その後、これらの述語は、のような論理演算によって組み合わせることができるor()and()カスタムフィルタオプションを形成すること。ユーザーのオプションのような、結果的に通話用のマップに追加したり、ユーザーがそれを要求するたびに飛ぶに計算することができ

BiPredicate<String, Message> titleAndDateFilter = 
    criteria.get("title").and(criteria.get("date"));

1あなたは使用することができますPredicate<Message>が、あなたが与えられた入力にメッセージのコンテキストを比較する必要があるため、それは、これらの機能はあまり孤立するだろう。
2私は、Java 9つのを使用しましたMap.of

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=211395&siteId=1