Java / Groovy:创建并读取两个对象的列表

时间:2016-10-21 15:39:24

标签: java groovy

如何定义和迭代两个对象的列表(Foo,Bar)?

我尝试了什么:

// 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类是解决方案我很好,我只希望有一个更简单的解决方案。

4 个答案:

答案 0 :(得分: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 :(得分:2)

考虑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
}

答案 2 :(得分:1)

为什么不使用列表清单?列表的每个元素都可以是一个包含FooBar实例的双元素列表。

为了在构造每个双元素Foo / Bar列表时增加安全性,编写一个帮助方法,使用TypeChecked并返回一个不可变列表以防止构造后篡改。

@TypeChecked
def makeFooBar(Foo foo, Bar bar) { 
    [foo, bar].asImmutable() 
}

def fooBars = [] 

// some code to populate the list...
fooBars << makeFooBar(new Foo(), new Bar())

// iterate and do something with each foo/bar pair
fooBars.each { fooBar ->
  def (foo, bar) = fooBar

}

一种类型的不安全区域是fooBars列表,可以使用其他对象类型填充。但是如果你想要那种程度的类型安全,那么也许你应该完全考虑另一种语言。

答案 3 :(得分:1)

为什么没有人建议地图?

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

似乎比元组列表更聪明。