Ваш вопрос приносит больше вопросов, чем ответов: если у вас есть массив или список строк, пусть ваш конструктор возьмет этот массив / список.
Если вам нужно преобразовать содержимое этого массива / списка вбольше вашего объекта, ваш ответ Stream
, вам не нужны сложные вещи, такие как рефлексия:
String[] myArray = ...;
MyType[] a = Arrays.stream(myArray).map(MyType::new).toArray(MyType[]::new);
Collection<String> coll = ...;
List<MyType> b = coll.stream().map(MyType::new).collect(Collectors.toList());
Вы, безусловно, можете сделать больше: если у вас есть конструктор с арностью 3 (пример: 3 String):
- Сначала мы создаем поток [0, size () / arity], который является номером объекта, который вам нужно построить.Умножьте его на арность, и вы получите индекс первого элемента, который будет передан вашему конструктору.
- Мы сопоставляем
index
с MyObj
: safeGet
позаботится о извлечении значения из списка (этобудет работать и с массивом, но вам просто нужно использовать вместо него length
и []
. MyObj
иметь конструктор, принимающий каждый ваш кортеж.Если конструктору необходимо преобразовать один из исходного объекта (String) в другой (например, целое число), то вам, вероятно, лучше использовать статический метод valueOf, выполняющий String для объекта. - Из
Stream
мы возвращаем массив, но вы можете использовать collect(toList())
для списка.
Вот первый пример:
public static void main(final String[] args) {
final List<String> list = Arrays.asList("A", "B", "C", "D", "E", "F");
// fails if list.size() is not multiple of 3
final int arity = 3;
final MyObj[] myObj = IntStream.range(0, list.size() / arity).map(n -> arity * n)
.mapToObj(index -> new MyObj(safeGet(list, index, 0), safeGet(list, index, 1), safeGet(list, index, 2)))
.toArray(MyObj[]::new)
;
}
private static <T> T safeGet(final List<T> list, final int baseIndex, final int relativeIndex) {
final int index = baseIndex + relativeIndex;
return index < list.size() ? list.get(index) : null;
}
static class MyObj {
public MyObj(final String a, final String b, final String c) {
}
}
Вот второй пример с конструктором, принимающим int
вместо String
:
public static void main(final String[] args) {
final List<String> list = Arrays.asList("A", "0", "C", "D", "2", "F");
// fails if list.size() is not multiple of 3
final int arity = 3;
final MyObj[] myObj = IntStream.range(0, list.size() / arity).map(n -> arity * n)
.mapToObj(index -> MyObj.valueOf(list, index))
.toArray(MyObj[]::new)
;
Arrays.stream(myObj).forEach(System.out::println);
}
private static <T> T safeGet(final List<T> list, final int baseIndex, final int relativeIndex) {
final int index = baseIndex + relativeIndex;
return index < list.size() ? list.get(index) : null;
}
static class MyObj {
public MyObj(final String a, final int b, final String c) {
}
public static MyObj valueOf(final List<String> source, final int baseIndex) {
final String a = safeGet(source, baseIndex, 0);
final int b = Integer.parseInt(safeGet(source, baseIndex, 1));
final String c = safeGet(source, baseIndex, 2);
return new MyObj(a, b, c);
}
}