2015-10-13 2 views
0

Например, у LibGDX framework есть пользовательские коллекции, такие как Array<T> и ObjectMap<K, V>, которые помогают производительности приложений/игр. Можно ли создать литерала для инициализации, чтобы Array мог быть инициализирован, например, [1,2,3,4] и ObjectMap с [key:"value"].Возможно ли реализовать инициализаторы литеральных литералов для пользовательских классов в Groovy?

Я знаю, что операторы доступа [] могут быть добавлены к объектам путем реализации методов putAt/getAt, но ничего не видели об буквальных инициализаторах.

Заблокированы ли они самим языком, как переопределение оператора в Java или есть способ создать инициализаторы списка/карты для пользовательских классов?

+0

Можете ли вы привести пример того, что вы имеете в виду? –

+0

Я думаю, что OP хочет получить ObjectMap от чего-то вроде '[x: 42]' вместо 'LinkedHashMap' (и я предполагаю, что это невозможно). @MrPlow вы можете по крайней мере избавиться от некоторого повторения с 'with'. – cfrick

+0

: '' [x: 42] как ObjectMap' не работает? –

ответ

3

Один из возможных способов заключается в манипулировании существующий LinkedHashMap.asType() метод принять ObjectMap в качестве параметра:

def originalMethod = LinkedHashMap.getMetaClass().getMetaMethod("asType", Class) 
LinkedHashMap.getMetaClass().asType = { Class clazz -> 
    if(clazz == ObjectMap) { 
     def map = new ObjectMap() 
     delegate.each { key, value -> map.put(key, value) } 
     map 
    } 
    else { 
     originalMethod.invoke(delegate, clazz) 
    } 
} 

Вы можете сделать:

def map = [a:1] as ObjectMap 

Другим вариантом было бы добавить метод toObjectMap() к основание Map metaClass like so:

Map.getMetaClass().toObjectMap = { -> 
    def map = new ObjectMap() 
    delegate.each { key, value -> map.put(key, value) } 
    map 
} 

Затем вы можете сделать:

def map2 = [a:2].toObjectMap() 

Или просто написать метод утилита для преобразования карты в ObjectMaps ;-)

+0

Я вижу. Хотя недостатком этого является то, что всегда будет два распределения. Один для временного LinkedHashMap (который вскоре после этого откроется и будет помечен для GC) и один для ObjectMap. Я предполагаю, что это то, что я должен буду принять (это не то, что я буду использовать литеральные карты для каждого тика). Спасибо за ответ. – MrPlow

+0

Простота использования всегда идет со стоимостью ;-) –

+0

Чтобы продлить ответ Тима. Если класс предоставляет конструктор, в котором каждый элемент списка соответствует (например, с Object []/Object ...), тогда будет работать строка типа ObjectMap map2 = [1,2,3] '. Это все равно создаст промежуточную ссылку LinkedHashMap, но будущая версия Groovy может оптимизировать это. – blackdrag