概要
- Java のメソッドで複数の値を返す方法について、標準ライブラリや外部ライブラリを使用したサンプルコードを挙げる (3つの値を返すサンプルコード)
環境
- Java 15 (AdoptOpenJDK 15+36)
- Gradle 6.6.1
- macOS Catalina
使用している外部ライブラリ
- Kotlin Standard Library 1.4.10
- Scala Standard Library 2.13.3
- Apache Commons Lang 3.11
- Functional Java 4.8.1
- javatuples 1.2
- jOOλ 0.9.14
- Reactor Core 3.3.10
- Vavr 0.10.3
外部ライブラリを使わない方法
標準ライブラリ java.lang.Object[]
Object の配列に値をセットして返す。
受け取った側はキャストが必要。
public class ArraySample {
static Object[] getArray() {
Object[] array = new Object[3];
array[0] = "foo";
array[1] = true;
array[2] = 123456;
return array;
}
public static void main(String[] args) {
Object[] array = getArray();
String foo = (String) array[0];
boolean bar = (boolean) array[1];
int baz = (int) array[2];
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
標準ライブラリ java.util.List
List の要素に値をセットして返す。
受け取った側はキャストが必要。
import java.util.ArrayList;
import java.util.List;
public class ListSample {
static List<Object> getList() {
ArrayList<Object> list = new ArrayList<>();
list.add("foo");
list.add(true);
list.add(123456);
return list;
}
public static void main(String[] args) {
List<Object> list = getList();
String foo = (String) list.get(0);
boolean bar = (boolean) list.get(1);
int baz = (int) list.get(2);
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
標準ライブラリ java.util.Map
Map の要素に値をセットして返す。
受け取った側はキャストが必要。
import java.util.HashMap;
import java.util.Map;
public class MapSample {
static Map<String, Object> getMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("foo", "foo");
map.put("bar", true);
map.put("baz", 123456);
return map;
}
public static void main(String[] args) {
Map<String, Object> map = getMap();
String foo = (String) map.get("foo");
boolean bar = (boolean) map.get("bar");
int baz = (int) map.get("baz");
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
クラスを定義する
クラスを定義してフィールドに値をセットして返す。
public class ClassSample {
static class MyClass {
String foo;
boolean bar;
int baz;
}
static MyClass getMyClass() {
MyClass cls = new MyClass();
cls.foo = "foo";
cls.bar = true;
cls.baz = 123456;
return cls;
}
public static void main(String[] args) {
MyClass cls = getMyClass();
String foo = cls.foo;
boolean bar = cls.bar;
int baz = cls.baz;
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
ジェネリクス化したクラスを定義する
ジェネリクス化したクラスを定義して、使用する際に型を指定する。
フィールドに値をセットして返す。
public class GenericsSample {
static class ValuesGenerics<T1, T2, T3> {
T1 foo;
T2 bar;
T3 baz;
}
static ValuesGenerics<String, Boolean, Integer> getGenerics() {
ValuesGenerics<String, Boolean, Integer> generics = new ValuesGenerics<>();
generics.foo = "foo";
generics.bar = true;
generics.baz = 123456;
return generics;
}
public static void main(String[] args) {
ValuesGenerics<String, Boolean, Integer> generics = getGenerics();
String foo = generics.foo;
boolean bar = generics.bar;
int baz = generics.baz;
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
レコードを定義する
レコード (Java 16 から正式導入予定) を定義して使用する。
public class RecordSample {
record ValuesRecord(String foo, boolean bar, int baz) {
}
static ValuesRecord getRecord() {
return new ValuesRecord("foo", true, 123456);
}
public static void main(String[] args) {
ValuesRecord record = getRecord();
String foo = record.foo;
boolean bar = record.bar;
int baz = record.baz;
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
参考: JEP 384: Records (Second Preview)
外部ライブラリを使う方法
Kotlin Standard Library (kotlin.Triple)
Kotlin の標準ライブラリを Java から使用する。
Kotlin の標準ライブラリには、2つの値を扱う Pair と、3つの値を扱う Triple がある。
import kotlin.Triple;
public class KotlinSample {
static Triple<String, Boolean, Integer> getTriple() {
return new Triple<>("foo", true, 123456);
}
public static void main(String[] args) {
Triple<String, Boolean, Integer> triple = getTriple();
String foo = triple.getFirst();
boolean bar = triple.getSecond();
int baz = triple.getThird();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
参考: Triple - Kotlin Programming Language
Scala Standard Library (scala.Tuple3)
Scala の標準ライブラリを Java から使用する。
Scala の標準ライブラリには、1つの値を扱う Tuple1 から、22個の値を扱う Tuple22 まである。
import scala.Tuple3;
public class ScalaSample {
static Tuple3<String, Boolean, Integer> getTuple3() {
return new Tuple3<>("foo", true, 123456);
}
public static void main(String[] args) {
Tuple3<String, Boolean, Integer> tuple = getTuple3();
String foo = tuple._1();
boolean bar = tuple._2();
int baz = tuple._3();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
参考: Scala Standard Library 2.13.3 - scala.Tuple3
Apache Commons Lang (org.apache.commons.lang3.tuple.Triple)
Apache Commons Lang には、2つの値を扱う Pair と、3つの値を扱う Triple がある。
import org.apache.commons.lang3.tuple.Triple;
public class ApacheCommonsLangSample {
static Triple<String, Boolean, Integer> getTriple() {
return Triple.of("foo", true, 123456);
}
public static void main(String[] args) {
Triple<String, Boolean, Integer> triple = getTriple();
String foo = triple.getLeft();
boolean bar = triple.getMiddle();
int baz = triple.getRight();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
参考: Triple (Apache Commons Lang 3.11 API)
Functional Java (fj.P3)
Functional Java には、1つの値を扱う P1 から、8個の値を扱う P8 まである。
import fj.P;
import fj.P3;
public class FunctionalJavaSample {
static P3<String, Boolean, Integer> getP3() {
return P.p("foo", true, 123456);
}
public static void main(String[] args) {
P3<String, Boolean, Integer> p = getP3();
String foo = p._1();
boolean bar = p._2();
int baz = p._3();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
javatuples (org.javatuples.Triplet)
javatuples には、1つの値を扱う Unit から、10個の値を扱う Decade まである。
import org.javatuples.Triplet;
public class JavatuplesSample {
static Triplet<String, Boolean, Integer> getTriplet() {
return Triplet.with("foo", true, 123456);
}
public static void main(String[] args) {
Triplet<String, Boolean, Integer> triplet = getTriplet();
String foo = triplet.getValue0();
boolean bar = triplet.getValue1();
int baz = triplet.getValue2();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
参考: Triplet (javatuples 1.2 API)
jOOλ (org.jooq.lambda.tuple.Tuple3)
jOOλ には、0個の値を扱う Tuple0 から、16個の値を扱う Tuple16 まである。
import org.jooq.lambda.tuple.Tuple;
import org.jooq.lambda.tuple.Tuple3;
public class JoolSample {
static Tuple3<String, Boolean, Integer> getTuple3() {
return Tuple.tuple("foo", true, 123456);
}
public static void main(String[] args) {
Tuple3<String, Boolean, Integer> tuple = getTuple3();
String foo = tuple.v1();
boolean bar = tuple.v2();
int baz = tuple.v3();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
Reactor (reactor.util.function.Tuple3)
Reactor には、2個の値を扱う Tuple2 から、8個の値を扱う Tuple8 まである。
import reactor.util.function.Tuple3;
import reactor.util.function.Tuples;
public class ReactorSample {
static Tuple3<String, Boolean, Integer> getTuple3() {
return Tuples.of("foo", true, 123456);
}
public static void main(String[] args) {
Tuple3<String, Boolean, Integer> tuple = getTuple3();
String foo = tuple.getT1();
boolean bar = tuple.getT2();
int baz = tuple.getT3();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
参考: Tuple3 (reactor-core 3.3.10.RELEASE)
Vavr (io.vavr.Tuple3)
Vavr には、0個の値を扱う Tuple0 から、8個の値を扱う Tuple8 まである。
import io.vavr.Tuple;
import io.vavr.Tuple3;
public class VavrSample {
static Tuple3<String, Boolean, Integer> getTuple3() {
return Tuple.of("foo", true, 123456);
}
public static void main(String[] args) {
Tuple3<String, Boolean, Integer> tuple = getTuple3();
String foo = tuple._1();
boolean bar = tuple._2();
int baz = tuple._3();
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
}
}
サンプルコード実行用ファイル
build.gradle
plugins {
id 'java'
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
// 必要なライブラリ群
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.4.10'
implementation 'org.scala-lang:scala-library:2.13.3'
implementation 'org.apache.commons:commons-lang3:3.11'
implementation 'org.functionaljava:functionaljava:4.8.1'
implementation 'org.javatuples:javatuples:1.2'
implementation 'org.jooq:jool:0.9.14'
implementation 'io.projectreactor:reactor-core:3.3.10.RELEASE'
implementation 'io.vavr:vavr:0.10.3'
}
sourceCompatibility = JavaVersion.VERSION_15
mainClassName = "App"
tasks.withType(JavaCompile) {
// Java 15 のプレビュー機能を使う
options.compilerArgs += ['--enable-preview']
}
application {
// Java 15 のプレビュー機能を使う
applicationDefaultJvmArgs = ['--enable-preview']
}
サンプルコードまとめて実行用クラス
public class App {
public static void main(String[] args) {
ArraySample.main(args);
ListSample.main(args);
MapSample.main(args);
ClassSample.main(args);
GenericsSample.main(args);
RecordSample.main(args);
KotlinSample.main(args);
ScalaSample.main(args);
ApacheCommonsLangSample.main(args);
FunctionalJavaSample.main(args);
JavatuplesSample.main(args);
JoolSample.main(args);
ReactorSample.main(args);
VavrSample.main(args);
}
}