0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Java8】大中小カテゴリを持つリストから項目取得

Posted at

はじめに

StreamAPIのfilterとreduceのお試し。
以下をEnumとStreamAPIで実装をしてみました。

  • 大中小のカテゴリコードを持つマスタがある。
  • 大中小を指定して項目を返す。
  • 大中配下の小の合計値を返す。

実装

カテゴリマスタ(Enum)

こんな感じで大中小を持つカテゴリマスタを用意します。

Category.java
package com.example.demo.categoryfilter;

public enum Category {
	EMPLOYEE_111(1,1,1), // 1部1課 社員1
	EMPLOYEE_112(1,1,2), // 1部1課 社員2
	EMPLOYEE_113(1,1,3), // 1部1課 社員3
	EMPLOYEE_121(1,2,1), // 1部2課 社員1
	EMPLOYEE_122(1,2,2), // 1部2課 社員2
	EMPLOYEE_123(1,2,3), // 1部2課 社員3
	EMPLOYEE_211(2,1,1), // 2部1課 社員1
	EMPLOYEE_212(2,1,2), // 2部1課 社員2
	;
	Category(int large,int medium,int small){
		this.large=large;
		this.medium=medium;
		this.small=small;
	}
	private int large; // 部コード
	private int medium; // 課コード
	private int small; // 社員コード
	public int getL() {
		return large;
	}
	public void setL(int large) {
		this.large = large;
	}
	public int getM() {
		return medium;
	}
	public void setM(int medium) {
		this.medium = medium;
	}
	public int getS() {
		return small;
	}
	public void setS(int small) {
		this.small = small;
	}
}

Filterメソッド

CategoryFilter.java
package com.example.demo.categoryfilter;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Optional;

public class CategoryFilter {

	/**
	 * 部署と課と社員コードを指定して社員名を返す。
	 * 
	 * @param list
	 * @param category
	 * @return 社員名
	 */
	public static String filter(List<Employee> list, Category category) {
		Optional<String> ret = list.stream()
				.filter(e -> e.getL() == category.getL())
				.filter(e -> e.getM() == category.getM())
				.filter(e -> e.getS() == category.getS())
				.map(e -> e.getName())
				.findFirst();
		return ret.orElse("名無しさん");
	}

	/**
	 * 部署と課を指定して配下の社員の給与を合計する。
	 * BigDecimalの処理はおまけ。
	 * 
	 * @param list
	 * @param category
	 * @return 給与合計
	 */
	public static BigDecimal sum(List<Employee> list, Category category) {
		Optional<BigDecimal> ret = list.stream()
				.filter(e -> e.getL() == category.getL())
				.filter(e -> e.getM() == category.getM())
				.map(e -> e.getSalary())
				.reduce((sum, i) -> sum.add(i));
		// 初期値0、小数点以下切り捨てで返す
		return ret.orElse(BigDecimal.ZERO).setScale(0, RoundingMode.DOWN);
	}
}

Employee

Employee.java
package com.example.demo.categoryfilter;

import java.math.BigDecimal;

import lombok.Data;

@Data
public class Employee {
	private int l;
	private int m;
	private int s;
	private String name;
	private BigDecimal salary;

	public Employee(Category category, String name, BigDecimal salary) {
		this.l = category.getL();
		this.m = category.getM();
		this.s = category.getS();
		this.name = name;
		this.salary = salary;
	}
	public Employee(Category category, String name, int salary) {
		this(category, name, new BigDecimal(salary));
	}
}

テストコード

七郎さんと八郎さんは異常系用。

CategoryFilterTests.java
package com.example.demo.categoryfilter;

import static org.hamcrest.CoreMatchers.is;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class CategoryFilterTests {
	private static List<Employee> list;

	@BeforeClass
	public static void before() {
		list = sample();
	}

	@Test
	public void test_filter1() {
		String name = CategoryFilter.filter(list, Category.EMPLOYEE_123);
		System.out.println("EMPLOYEE_123 name=" + name);
		Assert.assertThat(name, is("山田六郎"));
	}

	@Test
	public void test_filter2() {
		String name = CategoryFilter.filter(list, Category.EMPLOYEE_212);
		System.out.println("EMPLOYEE_212 name=" + name);
		Assert.assertThat(name, is("名無しさん"));
	}

	@Test
	public void test_sum1() {
		BigDecimal sum = CategoryFilter.sum(list, Category.EMPLOYEE_122);
		System.out.println("EMPLOYEE_122 sum=" + sum);
		Assert.assertThat(sum, is(new BigDecimal(600_000)));
	}

	@Test
	public void test_sum2() {
		BigDecimal sum = CategoryFilter.sum(list, Category.EMPLOYEE_212);
		System.out.println("EMPLOYEE_21 sum=" + sum);
		Assert.assertThat(sum, is(new BigDecimal(0)));
	}

	private static List<Employee> sample() {
		List<Employee> list = new ArrayList<>();
		list.add(new Employee(Category.EMPLOYEE_111, "山田一郎", 111_000));
		list.add(new Employee(Category.EMPLOYEE_112, "山田二郎", 112_000));
		list.add(new Employee(Category.EMPLOYEE_113, "山田三郎", 113_000));
		list.add(new Employee(Category.EMPLOYEE_121, "山田四郎", 100_000));
		list.add(new Employee(Category.EMPLOYEE_122, "山田五郎", 200_000));
		list.add(new Employee(Category.EMPLOYEE_123, "山田六郎", 300_000));
//		list.add(new Employee(Category.EMPLOYEE_211, "山田七郎", 211_000));
//		list.add(new Employee(Category.EMPLOYEE_212, "山田八郎", 212_000));
		list.forEach(System.out::println);
		System.out.println();
		return list;
	}
}

実行結果

ログ
Employee(l=1, m=1, s=1, name=山田一郎, salary=111000)
Employee(l=1, m=1, s=2, name=山田二郎, salary=112000)
Employee(l=1, m=1, s=3, name=山田三郎, salary=113000)
Employee(l=1, m=2, s=1, name=山田四郎, salary=100000)
Employee(l=1, m=2, s=2, name=山田五郎, salary=200000)
Employee(l=1, m=2, s=3, name=山田六郎, salary=300000)

EMPLOYEE_123 name=山田六郎
EMPLOYEE_212 name=名無しさん
EMPLOYEE_122 sum=600000
EMPLOYEE_21 sum=0

あとがき

やっぱりstream apiはキレイですねー。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?