Groovy method optimization to build > tokens I have a string array:

def invoices = [LEDES98BI V2,
LINE|INVOICE_DATE|INVOICE_NUMBER|INVOICE_TOTAL,
1|20150301|INV-Error_Test1|22,
2|20150301|INV-Error_Test1|24,
3|20150301|INV-Error_Test2|26,
4|20150301|INV-Error_Test2|28,]


I tried to convert it to HasMap&lt;String, List&lt;List&gt;&gt; with key as invoice numbers(INV-Error_Test1, INV-Error_Test2) and the values are each invoice line:

[
INV-Error_Test2:[[3,20150301, INV-Error_Test2,26], [4,20150301, INV-Error_Test2,28]], 
INV-Error_Test1:[[1,20150301, INV-Error_Test1,22], [2,20150301, INV-Error_Test1,24]]
]


And this is the method which converts the string array into &lt;String, List&lt;List&gt;&gt; tokens:

def extractInvoiceLineItems(def invoices) {
    Map invLineItems = new HashMap&lt;String, ArrayList&lt;ArrayList&gt;&gt;();
    def lineItems = []
    for(int i = 2; i&lt;invoices.length; i++){
       def tokens =  invoices[i].split('\\|') as List
       if(tokens.size != 1) {
        lineItems.add(tokens)           
      }
    }

    for (int i=0; i&lt; lineItems.size; i++) {
        invNumber = lineItems.get(i).get(1)
         if(invLineItems.keySet().find{it == invNumber}) {
            templineItem = invLineItems.get(invNumber)
            templineItem.add(lineItems.get(i))
            invLineItems.put(invNumber,templineItem)      
         }
        else {
            def list = []
            list.add(lineItems.get(i))
            invLineItems.put(invNumber,list)
        }      
    }
invLineItems
}


I am using lots of traditional for loops and am wondering whether it can be simplified further (using closures or any other way).
Yes, it can be simplified further. I divided the process into three steps and added comments and assertions to make it easier to see how it works.

// Simulate converting a CSV file into a list.
def csv = 
'''LEDES98BI V2
LINE|INVOICE_DATE|INVOICE_NUMBER|INVOICE_TOTAL
1|20150301|INV-Error_Test1|22
2|20150301|INV-Error_Test1|24
3|20150301|INV-Error_Test2|26
4|20150301|INV-Error_Test2|28'''.split(/\n/)

assert csv == [
    'LEDES98BI V2', 
    'LINE|INVOICE_DATE|INVOICE_NUMBER|INVOICE_TOTAL',
    '1|20150301|INV-Error_Test1|22',
    '2|20150301|INV-Error_Test1|24',
    '3|20150301|INV-Error_Test2|26',
    '4|20150301|INV-Error_Test2|28']

/* 
 * Ignore the first two csv lines and create a list of lists.
 * The inner lists represent the fields of each record.
 */
def invoices = csv[2..-1].collect { it.tokenize('|') }

assert invoices == [
    ['1', '20150301', 'INV-Error_Test1', '22'], 
    ['2', '20150301', 'INV-Error_Test1', '24'], 
    ['3', '20150301', 'INV-Error_Test2', '26'], 
    ['4', '20150301', 'INV-Error_Test2', '28']]

/*
 * Create a Map by grouping each record by its invoice number.
 */
invoices = invoices.groupBy { it[2] }

assert invoices == [
    'INV-Error_Test1':[
        ['1', '20150301', 'INV-Error_Test1', '22'],
        ['2', '20150301', 'INV-Error_Test1', '24']
    ], 
    'INV-Error_Test2':[
        ['3', '20150301', 'INV-Error_Test2', '26'],
        ['4', '20150301', 'INV-Error_Test2', '28']
    ]
]


Here's the same program in a condensed form to give you an idea of just how concisely this can be done:

'''LEDES98BI V2
LINE|INVOICE_DATE|INVOICE_NUMBER|INVOICE_TOTAL
1|20150301|INV-Error_Test1|22
2|20150301|INV-Error_Test1|24
3|20150301|INV-Error_Test2|26
4|20150301|INV-Error_Test2|28'''
    .split(/\n/)[2..-1]
    .collect { it.tokenize('|') }
    .groupBy { it[2] }