Я взял основной ответ и сделал его контейнером МОК, чтобы определить, где разделить. ( Для тех, кто действительно ищет только разделение на 3 элемента, при чтении этого сообщения при поиске ответа? )
Этот метод позволяет разделить на любой тип элемента как
public static List<List<T>> SplitOn<T>(List<T> main, Func<T, bool> splitOn)
{
int groupIndex = 0;
return main.Select( item => new
{
Group = (splitOn.Invoke(item) ? ++groupIndex : groupIndex),
Value = item
})
.GroupBy( it2 => it2.Group)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
Итак, для OP код будет
var it = new List<string>()
{ "a", "g", "e", "w", "p", "s", "q", "f", "x", "y", "i", "m", "c" };
int index = 0;
var result = SplitOn(it, (itm) => (index++ % 3) == 0 );
Вы можете вызвать частный метод с отражением. Изменение последнего бита опубликованного кода:
Method method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);
Существует несколько предостережений. Во-первых, getDeclaredMethod
найдет только метод, объявленный в текущем Class
, но не унаследованный от супертипов. Итак, перейдите по иерархии конкретного класса, если это необходимо. Во-вторых, SecurityManager
может предотвратить использование метода setAccessible
. Таким образом, может потребоваться выполнить функцию PrivilegedAction
(используя AccessController
или Subject
).
Если метод принимает не-примитивный тип данных, то для вызова частного метода любого класса можно использовать следующий метод:
public static Object genericInvokMethod(Object obj, String methodName,
int paramCount, Object... params) {
Method method;
Object requiredObj = null;
Object[] parameters = new Object[paramCount];
Class<?>[] classArray = new Class<?>[paramCount];
for (int i = 0; i < paramCount; i++) {
parameters[i] = params[i];
classArray[i] = params[i].getClass();
}
try {
method = obj.getClass().getDeclaredMethod(methodName, classArray);
method.setAccessible(true);
requiredObj = method.invoke(obj, params);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return requiredObj;
}
Принятые параметры: obj, methodName, количество параметров принятых и параметров. Например,
public class Test {
private String concatString(String a, String b) {
return (a+b);
}
}
Метод concatString может быть вызван как
Test t = new Test();
String str = (String) genericInvokMethod(t, "concatString", 2, "Hello", "Mr.x");
parameters
, с которым вы ничего не делаете?
– Paul Samsotha
10 August 2018 в 18:33
вы можете сделать это, используя ReflectionTestUtils of Sring (org.springframework.test.util.ReflectionTestUtils)
ReflectionTestUtils.invokeMethod(instantiatedObject,"methodName",argument);
Пример: если у вас есть класс с приватным методом "square (int x)"
Calculator calculator = new Calculator();
ReflectionTestUtils.invokeMethod(calculator,"square",10);
Используйте getDeclaredMethod()
, чтобы получить частный объект Method, а затем используйте method.setAccessible()
, чтобы разрешить его на самом деле.
java.lang.StackOverflowError
, если я не вызываю setAccessible(true)
.
– Robert Mark Bram
25 March 2013 в 12:11
Еще один вариант - использование очень мощной библиотеки JOOR https://github.com/jOOQ/jOOR
MyObject myObject = new MyObject()
on(myObject).get("privateField");
Позволяет изменять любые поля, такие как конечные статические константы и вызывать защищенные методы без указания конкретного класса в иерархии наследования
<!-- https://mvnrepository.com/artifact/org.jooq/joor-java-8 -->
<dependency>
<groupId>org.jooq</groupId>
<artifactId>joor-java-8</artifactId>
<version>0.9.7</version>
</dependency>
getDeclaredMethod()
вместо простоgetMethod()
- это не будет работать для частных методов. – Ercksen 14 December 2015 в 21:32