2016-10-21 2 views
0

Как определить и перебрать список из двух объектов (Foo, Bar)?Java/Groovy: создать и прочитать список из двух объектов

Что я пробовал:

// create 
def fooBar = new ArrayList<Foo, Bar>() 
fooBar.add(new Foo()) 
fooBar.add(new Bar()) 
fooBar.add(new Foo()) // << shouldn't be allowed or overwrite first foo 

def fooBars = new ArrayList<List<Foo, Bar>>() 
fooBars << fooBar 

// read 
fooBars.each { fooBar -> 
    def foo = fooBar[0] 
    def bar = fooBar[1] 
    // do something with foo and bar 
} 

Что я хочу:

// pseudo code 
def fooBar = new ???<Foo, Bar>() 
fooBar.set(new Foo()) 
fooBar.set(new Bar()) 

def fooBars = new ArrayList<???>() 
fooBars << fooBar 

fooBars.each { fooBar -> 
    def foo = fooBar[???] // 0, 'foo', ..? 
    def bar = fooBar[???] 
    // do something with foo and bar 
} 

При создании моего собственного класса FooBar этого решения, я в порядке, я просто надеюсь, что есть более простое решение.

+0

Вы можете попробовать 'new AbstractMap.SimpleEntry (...)' –

+1

Непонятно, что именно вы пытаетесь сделать. Вы пытаетесь создать список, в котором каждый элемент списка будет либо Foo, либо Bar? Если да, то вы хотите 'ArrayList '. Похоже, вы также можете создать список пар Foos и Bars, и в этом случае вам нужно будет либо использовать некоторый класс 'Pair ', заданный в некоторой библиотеке где-нибудь, либо написать свой собственный, а затем составить список что. – user3030010

+0

@ user3030010 Как я понял, OP хочет список ровно 2 элемента: один Foo и один бар. Другими словами, кортеж/пара. –

ответ

4

У Groovy есть понятие Tuples.

def tuple = new Tuple('one', 1) 
def (String a, Integer b) = tuple 
println a 
println b 

или альтернативно

def doSomething(String s, Integer i) { 
    println s 
    println i 
} 
doSomething(tuple) 

или альтернативно

def doSomething(Tuple t) { 
    println t[0] 
    println t[1] 
} 
doSomething(tuple) 

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

def tuples = [ ] << tuple << tuple 
tuples.each { doSomething(it) } 
+1

И если вам нужны дженерики, есть 'Tuple2', то есть:' new Tuple2 (foo, bar) ' –

1

Рассмотрим в Groovy Expando. Например:

class Foo {} 
class Bar {} 

def fooBar = new Expando() 
fooBar."foo" = new Foo() 
fooBar."bar" = new Bar() 

def fooBars = [] 
fooBars << fooBar 

fooBars.each { item -> 
    def foo = item."foo" 
    def bar = item."bar" 

    assert foo instanceof Foo 
    assert bar instanceof Bar 
} 
1

Почему бы не просто использовать список списков? Каждый элемент списка может быть двухэлементным списком, содержащим пример Foo и Bar в этом порядке.

Для дополнительной безопасности при создании каждого двухэлементного списка Foo/Bar напишите вспомогательный метод TypeChecked и верните неизменный список, чтобы предотвратить фальсификацию после строительства.

В связи с небезопасной областью один типа является fooBars списка, который может быть заполнен с другими типами объектов. Но если вы хотите такую ​​степень безопасности типов, то, возможно, вам стоит рассмотреть другой язык.

+0

Спасибо за ваш ответ. Что вы имеете в виду под «рассмотрением другого языка»? (Я пришел из PHP world btw) :) – MonkeyMonkey

+0

Я просто имел в виду, что если вы хотите использовать дженерики и иметь что-то значить, вы должны рассмотреть Java вместо Groovy.Groovy, по умолчанию, строго не соблюдает общие подписи; он с радостью выполнит код 'List list = ['hi', 'there']'. Но лучший способ справиться с этой слабостью, на мой взгляд, заключается в том, чтобы принять отношение Groovy и написать свой код как 'def list = ['hi', 'there']'. В целом, однако, если вы пришли с точки зрения PHP, я думаю, что Groovy подойдет вам хорошо. – bdkosher

0

Почему никто не предлагал карту?

def x = [:] 
x['foo'] = new Bar() 

Кажется немного умнее, чем список кортежей.

Смежные вопросы