Внесите следующие изменения в свой класс адаптера и проверьте один раз
@Override
public int getCount() {
//return 0;
return songs.size();
}
Если Вы хотите сделать это с Delphi, Вы могли бы изучить как JclExprEval
работы единицы, часть Библиотеки Кода ДЖЕДАЯ. Я записал это несколько лет назад (это немного сверхспроектировано); это анализирует функции и переменные и может вручить Вам назад указатель метода, который оценивает выражение быстро. Передайте переменные в ссылкой, и можно изменить их непосредственно, и переоцененное выражение будет вычислено соответственно.
В любом случае основы того, как это работает, могут быть полезными для Вас. Синтаксический анализ методом рекурсивного спуска выражений легок, и путем создания дерева, которое можно оценить многократно без перепарсинга. JclExprEval на самом деле генерирует код для простой стековой машины, так, чтобы он мог работать немного быстрее, чем древовидная интерпретация; стековые машины в основном ограничивают свои операции памяти массивами и используют переключатели для кодов операций, в то время как древовидная интерпретация переходит по ссылкам всюду по "куче" и часто использует виртуальную отправку (или двойную отправку) для кодов операций, таким образом, они обычно заканчивают медленнее.
Проявление того же подхода как JclExprEval
в парсинге, но записанный в C# и создании Expression
, как Marc предлагает, другой совершенно допустимый подход. Скомпилированное в JIT выражение должно быть вполне немного быстрее, чем интерпретируемая программа выражения или дерево, которые самостоятельно намного быстрее, чем парсинг.
В C# с.NET 3.5, можно использовать Expression
для этого; можно создать параметризованное выражение и затем скомпилировать его в делегата. Это точно, что я сделал для аспекта математики Finguistics. У меня все еще есть код парсинга, который я использовал, если Вы хотите его...
Основной прием, который я использовал, был то, что для хранения типа делегата известным я использовал массив в качестве входного типа - обработка другого args как прибытие [0], arr1, прибытие [2] и т.д. Это означает, что я мог скомпилировать в (например), a Func<decimal[], decimal>
(берет массив decimal
s, a возвратов decimal
).
После того как Вы звонили Compile()
, это симпатично как, хотя у Вас был код, чтобы сделать это непосредственно.
(редактирование)
Как краткий пример использования Expression
таким образом (с трудно кодированной функцией), посмотрите ниже. Синтаксический анализатор я уже в настоящее время писал работы как средство проверки предиката - т.е. проверять это"? + (2 *?-?) = 22 +?" - но не было бы трудно изменить его для возврата результата вместо этого (и представлять больше операций, как sin
/pow
/ и т.д. - по-видимому, путем отображения их непосредственно на открытые методы для объекта помощника (через Expression.Call
)).
using System;
using System.Linq.Expressions;
static class Program
{
static void Main()
{
var args = Expression.Parameter(typeof(float[]), "args");
var x = Expression.ArrayIndex(args, Expression.Constant(0));
var y = Expression.ArrayIndex(args, Expression.Constant(1));
var add = Expression.Add(x, y);
var lambda = Expression.Lambda<Func<float[], float>>(add, args);
Func<float[], float> func = lambda.Compile();
Console.WriteLine(func.Call(1, 2));
Console.WriteLine(func.Call(3, 4));
Console.WriteLine(func.Call(5, 6));
}
static T Call<T>(this Func<T[], T> func, params T[] args)
{ // just allows "params" usage...
return func(args);
}
}