Peta di Groovy

1. Ikhtisar

Groovy memperluas API Peta di Java untuk menyediakan metode operasi seperti pemfilteran, pencarian, dan penyortiran . Ini juga menyediakan berbagai cara singkat untuk membuat dan memanipulasi peta.

Di artikel ini, kita akan melihat cara Groovy bekerja dengan peta.

2. Membuat Peta Groovy s

Kita dapat menggunakan sintaks literal peta [k: v] untuk membuat peta. Pada dasarnya, ini memungkinkan kita untuk membuat instance peta dan menentukan entri dalam satu baris.

Peta kosong dapat dibuat dengan menggunakan:

def emptyMap = [:]

Demikian pula, peta dengan nilai dapat dibuat menggunakan:

def map = [name: "Jerry", age: 42, city: "New York"]

Perhatikan bahwa kunci tidak diapit tanda kutip.

Dan secara default Groovy membuat instance java.util.LinkedHashMap . Kita bisa mengganti perilaku default ini dengan menggunakan sebagai operator.

3. Menambahkan Item

Mari kita mulai dengan mendefinisikan peta:

def map = [name:"Jerry"]

Kami dapat menambahkan kunci ke peta:

map["age"] = 42

Tetapi cara lain yang lebih mirip Javascript adalah menggunakan notasi properti (operator titik):

map.city = "New York"

Dengan kata lain, Groovy mendukung pengaksesan pasangan nilai kunci dengan gaya seperti kacang.

Kita juga bisa menggunakan variabel sebagai ganti literal sebagai kunci sambil menambahkan item baru ke peta:

def hobbyLiteral = "hobby" def hobbyMap = [(hobbyLiteral): "Singing"] map.putAll(hobbyMap) assertTrue(hobbyMap.hobby == "Singing") assertTrue(hobbyMap[hobbyLiteral] == "Singing")

Pertama, kita harus membuat variabel baru yang menyimpan key hobby. Kemudian kami menggunakan variabel ini dalam tanda kurung dengan sintaks literal peta untuk membuat peta lain.

4. Mengambil Item

Sintaks literal atau notasi properti dapat digunakan untuk mendapatkan item dari peta.

Untuk peta yang didefinisikan sebagai:

def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]

Kita bisa mendapatkan nilai yang sesuai dengan nama kunci :

assertTrue(map["name"] == "Jerry")

atau

assertTrue(map.name == "Jerry")

5. Menghapus Item

Kita bisa menghapus entri apa pun dari peta berdasarkan kunci menggunakan metode remove () . Namun, terkadang kami mungkin perlu menghapus beberapa entri dari peta. Ini bisa dilakukan dengan menggunakan metode minus () .

Metode minus () menerima Map . Dan mengembalikan Peta baru setelah menghapus semua entri dari peta yang diberikan dari peta yang mendasarinya:

def map = [1:20, a:30, 2:42, 4:34, ba:67, 6:39, 7:49] def minusMap = map.minus([2:42, 4:34]); assertTrue(minusMap == [1:20, a:30, ba:67, 6:39, 7:49])

Selanjutnya, kami juga dapat menghapus entri berdasarkan suatu kondisi. Ini bisa dicapai dengan menggunakan metode removeAll () :

minusMap.removeAll{it -> it.key instanceof String} assertTrue(minusMap == [1:20, 6:39, 7:49])

Sebaliknya, untuk mempertahankan semua entri yang memenuhi suatu kondisi, kita dapat menggunakan metode retretAll () :

minusMap.retainAll{it -> it.value % 2 == 0} assertTrue(minusMap == [1:20])

6. Iterasi Melalui Entri

Kita bisa melakukan iterasi melalui entri menggunakan metode each () dan eachWithIndex () .

Metode each () menyediakan parameter implisit seperti entri , kunci , dan nilai yang sesuai dengan Entri saat ini .

Metode eachWithIndex () juga menyediakan indeks selain Entry . Kedua metode menerima Penutupan sebagai argumen.

Dalam contoh berikutnya, kami mengulangi setiap Entri. The Penutupan diteruskan ke masing-masing () metode mendapatkan pasangan kunci-nilai dari entri parameter implisit dan mencetaknya:

map.each{entry -> println "$entry.key: $entry.value"}

Selanjutnya, kami menggunakan metode eachWithIndex () untuk mencetak indeks saat ini bersama dengan nilai lainnya:

map.eachWithIndex{entry, i -> println "$i $entry.key: $entry.value"}

Mungkin juga untuk meminta kunci , nilai, dan indeks diberikan secara terpisah:

map.eachWithIndex{key, value, i -> println "$i $key: $value"}

7. Penyaringan

Kita bisa menggunakan metode find (), findAll () dan grep () untuk memfilter dan mencari entri peta berdasarkan kunci dan nilai.

Mari kita mulai dengan mendefinisikan peta untuk menjalankan metode ini di:

def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]

Pertama, kita melihat metode find () yang menerima Penutupan dan mengembalikan Entri pertama yang cocok dengan kondisi Penutupan :

assertTrue(map.find{it.value == "New York"}.key == "city")

Similarly, findAll also accepts a Closure but returns a Map with all the key-value pairs that satisfy the condition in the Closure:

assertTrue(map.findAll{it.value == "New York"} == [city : "New York"])

If we'd prefer to use a List, though, we can use grep instead of findAll:

map.grep{it.value == "New York"}.each{it -> assertTrue(it.key == "city" && it.value == "New York")}

We first used grep to find entries which have the value as New York. Then, to demonstrate the return type is List, we iterate through the result of grep(). And for each Entry in the list which is available in the implicit parameter, we check if its the expected result.

Next, to find out if all the items in a map satisfy a condition we can use every which returns a boolean.

Let's check if all values in the map are of type String:

assertTrue(map.every{it -> it.value instanceof String} == false)

Similarly, we can use any to determine if any items in the map match a condition:

assertTrue(map.any{it -> it.value instanceof String} == true)

8. Transforming and Collecting

At times we may want to transform the entries in a map into new values. Using the collect() and collectEntries() methods it's possible to transform and collect entries into a Collection or Map respectively.

Let's look at some examples.

Given a map of employee ids and employees:

def map = [ 1: [name:"Jerry", age: 42, city: "New York"], 2: [name:"Long", age: 25, city: "New York"], 3: [name:"Dustin", age: 29, city: "New York"], 4: [name:"Dustin", age: 34, city: "New York"]]

We can collect the names of all employees into a list using collect():

def names = map.collect{entry -> entry.value.name} assertTrue(names == ["Jerry", "Long", "Dustin", "Dustin"])

Next, if we're interested in a unique set of names, we can specify the collection by passing a Collection object:

def uniqueNames = map.collect([] as HashSet){entry -> entry.value.name} assertTrue(uniqueNames == ["Jerry", "Long", "Dustin"] as Set)

If we want to change the employee names in the map from lowercase to uppercase, we can use collectEntries. This method returns a map of transformed values:

def idNames = map.collectEntries{key, value -> [key, value.name]} assertTrue(idNames == [1:"Jerry", 2:"Long", 3:"Dustin", 4:"Dustin"])

Lastly, it's also possible to use collect methods in conjunction with the find and findAll methods to transform the filtered results:

def below30Names = map.findAll{it.value.age  value.name} assertTrue(below30Names == ["Long", "Dustin"])

Here, we first find all employees between ages 20-30 and collect them into a map.

9. Grouping

Sometimes we may want to group some items of a map into submaps based on a condition.

The groupBy() method returns a map of maps. And each map contains key-value pairs which evaluate to the same result for the given condition:

def map = [1:20, 2: 40, 3: 11, 4: 93] def subMap = map.groupBy{it.value % 2} assertTrue(subMap == [0:[1:20, 2:40], 1:[3:11, 4:93]])

Another way of creating submaps is by using subMap(). It is different in groupBy() in the sense that it only allows for grouping based on the keys:

def keySubMap = map.subMap([1,2]) assertTrue(keySubMap == [1:20, 2:40])

In this case, the entries for keys 1 and 2 are returned in the new map, and all the other entries are discarded.

10. Sorting

Usually, when sorting, we may want to sort the entries in a map based on key or value or both. Groovy provides a sort() method which can be used for this purpose.

Given a map:

def map = [ab:20, a: 40, cb: 11, ba: 93]

If sorting needs to be done on key, use the no-args sort() method which is based on natural ordering:

def naturallyOrderedMap = map.sort() assertTrue([a:40, ab:20, ba:93, cb:11] == naturallyOrderedMap)

Atau gunakan metode sort (Comparator) untuk memberikan logika perbandingan:

def compSortedMap = map.sort({k1, k2 -> k1  k2} as Comparator) assertTrue([a:40, ab:20, ba:93, cb:11] == compSortedMap)

Selanjutnya, untuk mengurutkan salah satu kunci atau nilai atau keduanya, kita dapat menyediakan kondisi Penutupan ke sort () :

def cloSortedMap = map.sort({it1, it2 -> it1.value  it1.value}) assertTrue([cb:11, ab:20, a:40, ba:93] == cloSortedMap)

11. Kesimpulan

Kami mulai dengan melihat bagaimana kami dapat membuat Peta di Groovy. Selanjutnya, kami melihat berbagai cara di mana item dapat ditambahkan, diambil, dan dihapus dari peta.

Kemudian, kami membahas metode untuk melakukan operasi umum yang disediakan di luar kotak di Groovy. Mereka termasuk memfilter, mencari, mengubah, dan menyortir.

Seperti biasa, contoh yang tercakup dalam artikel dapat ditemukan di GitHub.