Удалось заставить его работать, если это кому-нибудь поможет:
string request_code = "";
if (dict.TryGetValue("data", out data))
{
int dataLength = ((List<object>)data).Count;
for (int i = 0; i < dataLength; i++)
{
var rc = ((List<object>)data)[i];
var rc2 = (((Dictionary<string, object>)rc)["id"]);
request_code = (string)rc2;
Debug.Log("request_code=" + request_code);
}
}
public static<T> List<T> cons(List<T> list, T t) {
ArrayList<T> result = new ArrayList<T>(list);
result.add(0, t);
return result;
}
Отредактировано в ответ на комментарии: Поскольку вопрос задавался о «самом простом и / или наиболее эффективном способе реализации минусов», я выбрал «самый простой». Я не удивлюсь, узнав, что есть более эффективные способы. Размещение элемента перед списком - это еще один правильный подход, и первоначальное выделение правильного размера может, вероятно, повысить производительность. Преждевременная оптимизация - корень всего зла.
Clojure предоставляет подобные вещи из Lisp-y. В то время как большинство людей думают об использовании Clojure для языка (как и я), все библиотеки Clojure представляют собой настоящий код Java, и вы можете использовать структуры данных из Java как просто специальную библиотеку, если хотите. Таким образом, вы получите способность делать минусы и тому подобное, и вы получите неизменность, которую использует Clojure. Строковые данные Clojure также реализуют эквивалентные типы Java.
Просто мысль из другого направления.
Не могли бы вы использовать CompositeCollection ?
public Collection cons(Collection c1, Collection c2)
{
CompositeCollection cons = new CompositeCollection();
cons.addComposited(c1);
cons.addComposited(c2);
return cons;
}
Это не будет зависеть от того, является ли один из параметров неизменным и поддерживается ли исходная коллекция c1 и c2.
Если вам нужен список
, я бы, вероятно, сделал следующее:
public List cons(Collection c1, Collection c2)
{
ArrayList cons = new ArrayList(c1.size() + c2.size());
cons.addAll(c1);
cons.addAll(c2);
return cons;
}
Поскольку вы упоминаете функцию cons
, я предполагаю, что вы подходите к этой проблеме с концептуальной моделью связанных списков, состоящих из ячеек cons
, В частности, я предполагаю, что вы думаете о каждом списке, имеющем car
(первый элемент) и cdr
(подсписок, содержащий все следующие элементы).
Java поддерживает связанный перечисляет как java.util.LinkedList
. Они хороши для линейного обхода и могут очень эффективно вставлять элементы. Они наиболее похожи на связанные списки, о которых я упоминал выше.
Java также предлагает java.util.ArrayList
. Списки такого типа хороши для произвольного доступа, но могут быть медленными при вставке элементов. По факту, они медленнее всего при вставке элемента в начале списка. Поскольку ArrayList
реализованы как массивы за сценой, каждый элемент должен быть скопирован на одну позицию вперед в списке, чтобы освободить место для нового первого элемента. Теперь, если вам также понадобится массив большего размера, ArrayList
выделит новый массив, скопирует все элементы и т. Д.
(цитируется Google ImmutableList
как «произвольный доступ», поэтому он, скорее всего, больше похож на последний.)
Если вы планируете часто использовать метод cons
, я рекомендую использовать его со связанными списками. Операция cons
по существу добавляет элемент в начало списка. Это имеет мало смысла для линейных структур, таких как массивы. Я рекомендую не использовать списки массивов по этой причине: что они концептуально не подходят для работы.
Для очень требовательного: поскольку новый список возвращается каждый раз, когда вызывается cons
, копирование должно происходить независимо от того, является ли список LinkedList
или ArrayList
. Однако весь принцип операции cons
заключается в том, что она работает со связанным списком.
public <E> LinkedList<E> cons(E car, List<E> cdr) {
LinkedList<E> destination = new LinkedList<E>(cdr);
destination.addFirst(car);
return destination;
}
Обратите внимание, что приведенный выше код был написан после прочтения вышеупомянутых ответов, поэтому я прошу прощения за любой случайный плагиат. Дайте мне знать, если вы увидите это, и я правильно подтвердю.
Предполагая, что вы счастливы вернуть LinkedList
, вы можете использовать ImmutableList
в качестве cdr
в этом примере.
cons
, копирование должно происходить независимо от того, является ли список LinkedList
или ArrayList
. Однако весь принцип операции cons
заключается в том, что она работает со связанным списком.
public <E> LinkedList<E> cons(E car, List<E> cdr) {
LinkedList<E> destination = new LinkedList<E>(cdr);
destination.addFirst(car);
return destination;
}
Обратите внимание, что приведенный выше код был написан после прочтения вышеупомянутых ответов, поэтому я прошу прощения за любой случайный плагиат. Дайте мне знать, если вы увидите это, и я правильно подтвердю.
Предполагая, что вы счастливы вернуть LinkedList
, вы можете использовать ImmutableList
в качестве cdr
в этом примере.
cons
, копирование должно происходить независимо от того, является ли список LinkedList
или ArrayList
. Однако весь принцип операции cons
заключается в том, что она работает со связанным списком.
public <E> LinkedList<E> cons(E car, List<E> cdr) {
LinkedList<E> destination = new LinkedList<E>(cdr);
destination.addFirst(car);
return destination;
}
Обратите внимание, что приведенный выше код был написан после прочтения вышеупомянутых ответов, поэтому я прошу прощения за любой случайный плагиат. Дайте мне знать, если вы увидите это, и я правильно подтвердю.
Предполагая, что вы счастливы вернуть LinkedList
, вы можете использовать ImmutableList
в качестве cdr
в этом примере.
cons
заключается в том, что она работает со связанным списком.
public <E> LinkedList<E> cons(E car, List<E> cdr) {
LinkedList<E> destination = new LinkedList<E>(cdr);
destination.addFirst(car);
return destination;
}
Обратите внимание, что приведенный выше код был написан после прочтения приведенных выше ответов, поэтому я прошу прощения за любой случайный плагиат. Дайте мне знать, если вы увидите это, и я правильно подтвердю.
Предполагая, что вы счастливы вернуть LinkedList
, вы можете использовать ImmutableList
в качестве cdr
в этом примере.
cons
заключается в том, что она работает со связанным списком.
public <E> LinkedList<E> cons(E car, List<E> cdr) {
LinkedList<E> destination = new LinkedList<E>(cdr);
destination.addFirst(car);
return destination;
}
Обратите внимание, что приведенный выше код был написан после прочтения приведенных выше ответов, поэтому я прошу прощения за любой случайный плагиат. Дайте мне знать, если вы увидите это, и я правильно подтвердю.
Предполагая, что вы счастливы вернуть LinkedList
, вы можете использовать ImmutableList
в качестве cdr
в этом примере.
Конечно, LinkedList был бы наиболее эффективным способом вставки элемента в начало списка?
Просто используйте класс LinkedList , который поставляется с Java
Еще один вариант, если у вас есть только Iterable.
public static <E> List<E> cons(E e, Iterable<E> iter) {
List<E> list = new ArrayList<E>();
list.add(e);
for(E e2: iter) list.add(e2);
return list;
}
public static <E> List<E> cons(Iterable<E>... iters) {
List<E> list = new ArrayList<E>();
for(Iterable<E> iter: iters) for(E e1: iter1) list.add(e1);
return list;
}
Я собираюсь бросить свои 2 цента, а потом посмотрю, не придумает ли кто-нибудь что-нибудь более элегантное. В общем случае:
<E> List<E> cons(E e, List<E> list) {
List<E> res = Lists.newArrayListWithCapacity(list.size() + 1);
res.add(e);
res.addAll(list);
return res;
}
С ImmutableList
(не знаю, насколько это эффективно):
<E> ImmutableList<E> cons(E e, ImmutableList<E> list) {
return ImmutableList.<E>builder()
.add(e)
.addAll(list)
.build();
}
Я считаю, что ответ, который вы действительно ищете, таков:
http://functionaljava.googlecode.com/svn/artifacts/2.20/javadoc/fj/data/List. html
Этот метод даже называется cons
.
У меня нет опыта работы с этой библиотекой. Только что слышал об этом на днях. Надеюсь, все хорошо!
Эффективным решением было бы создать собственную реализацию списка с ленивым делегированием. Если его нельзя изменить, это не составит особого труда. Если он создан с помощью фабричного метода, вы даже можете использовать одну из двух различных базовых реализаций в зависимости от того, реализует ли список аргументов RandomAccess или нет.
Для простейшего случая (не проверял, компилируется ли это, нет проверок работоспособности и т. Д.):
class ConsList<E> extends AbstractList<E>
{
private final E first;
private final List<E> rest;
ConsList( E first, List<E> rest )
{
this.first = first;
this.rest = rest;
}
public int get( int index )
{
return (index == 0) ? first : rest.get( index - 1 );
}
public int size()
{
return rest.size() + 1;
}
}
Я уверен, что некоторые другие методы можно было бы сделать более эффективными, и последовательный случай мог бы быть лучше, если вместо этого расширить AbstractSequentialList.