W pełni obiektowyInterpretowany i kompilowany Kompilowany do JVM Bytecode Umożliwia korzystanie z bibliotek Java Skonstruowany z myślą o wysokiej produktywności Składnia podobna do JavaSilne i dynamiczne typowanie Wbudowane typy list, map oraz wyrazenia regularne Clousures
Podstawowe wiadomości # Nie jest wymagane używacie '()' i ';' log.info 'hello, world’ # - Wymagane jest użycie ';' do # separowanie instrukcji w linii log.info ‘Hello '; log.info ‘World ' # Do definiowania zmiennych używamy instrukcji 'def' def a = 'world' # Definicje oddzielamy znakiem ',' def c = 'Groovy. ', d = 'First steps' # Operator '==' porównuje wartości def b = 'world' assert a == b # Domyślnie klasy i funkcje są publiczne # getery i settery generowane są automatycznie Class Simple{ def greetings() { log.info ‘Hello’} } sef s = new Simple(); s.greetings() #Domyślnieimportowane pakiety : java.io. * java.lang.*java.util.*java.net.*java.math.BigDecimaljava.math.BigIntegergroovy.lang.*groovy.util.*
Zmienne tekstowe # Funkcja println wyświetla tekst oraz przechodzi do nowej linii log.info 'hello, world‘ # Znak '+' łączy teksty log.info 'hello' + ', ' + 'world' # Teksty z użyciem zmiennych tworzyć można używając znaku '+ ' lub '$' def g = 7, groovy = 10.2; log.info g + ', ' + groovy + '\n' def b= 'hello', c= 'world'; log.info "$b, ${c}" # Przykłady innych operacji na tekstach assert firstname * 2 == ‘KateKate’ assert fullname – firstname == ‘ Bush’ def path = /C:\Windows\System32/ ' Stałe tekstowe w jednej linii można otoczyć je apostrofami... ' '''... lub trzema apostrofami jeśli będą składać się z większej ilości linii lub będziemy chcieli ignorować znaki komentrzy://, */, oraz /*... ''' "... lub w apostrofy..." """... lub w potrójne apostrofy jeśli będą składać się z większej ilości linii """
Typy numeryczne # Podstawowe typy JAVA mają krótkie... assert 4.class == Integer # i długie nazwy assert 4.class == java.lang.Integer # Domyślnie liczby zmiennoprzecinkowe są typu BigDecimal assert 4.5.class == BigDecimal # Zamiana typów tekstowych na numeryczne def string = ”300”; assert string.isNumber() def i0 = Integer.parseInt(string) def i1 = string.toInteger() def i2 = string as Integer string = ”300.5” def n0 = string.toFloat() def n1 = string.toDouble() def n2 = string.toBigDecimal() Typy numeryczne w Groovy’mjava.lang.Integer:15, 0x1234ffffjava.lang.Long 100L, 200lajava.lang.Float 1.23f, 4.56Fjava.lang.Double 1.23d, 4.56Djava.math.BigInteger 123g, 456Gjava.math.BigDecimal 1.23, 1.4E4, 2.8e4 Typy numeryczne w Groovy’mjava.lang.Integer:15, 0x1234ffffjava.lang.Long 100L, 200lajava.lang.Float 1.23f, 4.56Fjava.lang.Double 1.23d, 4.56Djava.math.BigInteger 123g, 456Gjava.math.BigDecimal 1.23, 1.4E4, 2.8e4
Listy # DługoSC listy assert list2.size() == 3 # Elementy listy możne wskazać względem początku lub końca listy assert list2[1] == ‘Jan’ assert list2[-2] == ‘Jan’ # Dodawanie elementów do listy list1 << 5; assert list2.size() == 1 list1 << 7 << 'i' << 11; assert list1 == [5, 7, 'i', 11] assert [1,2] [4,5] + 6 == [1, 2, 3, 4, 5, 6] # Usuwanie elementów z listy assert ['a', 'b', 'c'] - ‘b' == ['a', 'c'] # Inne operacje na listach assert [6,3,9,2,7,1,5].sort() == [1,2,3,5,6,7,9] assert [6,3,9,2,7,1,5].max() == 9 assert [1,2,3,4,5,6].sum() == 21 Listy definiujemy przy użyciu znaków []def list1 = []def list = [element, element, element]Listy w Groovy’m mogą zawierac elementy różnych typówdef list2 = [3, ‘Jan’, new Date() ] Listy definiujemy przy użyciu znaków []def list1 = []def list = [element, element, element]Listy w Groovy’m mogą zawierac elementy różnych typówdef list2 = [3, ‘Jan’, new Date() ]
Zakresy # Zakres numeryczny zawierający górną granice... assert 5..8 == [5, 6,7, 8] #...lub nie górnej granicy assert 5..<8 == [5, 6, 7] # Zakresach mogą być również innych typów, np. typu String... assert ('a'..'d') == ['a','b','c','d'] # lub typu Date def today = new Date() def yesterday = today-1 assert (yesterday..today).size() == 2 # Inne przykłady użycia zakresów assert [ 1, *3..5, 7, *9..<12 ] == [1,3,4,5,7,9,10,11] assert ('a'..'g')[ 3..5 ] == ['d','e','f'] assert ('a'..'g')[-5..-2] == ['c','d','e','f'] assert ('a'..'g')[ 1, 3..5 ] == ['b','d','e','f'] # Istnieje kilka sposobów odwołania się do elementów mapy... assert map1.id == 'FX-17' assert map1['id'] == 'FX-17' assert map1.getAt('id') == 'FX-17‘ assert http[200] == 'OK' #...podobnie jest przy wstawianiu elementów map2.name = 'Potato' map2[-1] = 'washed, but not peeled' Zakres (ang. range) definiujemy używając symboli ”..” lewa_granica..prawa_granica(lewa_granica..prawa_granica)(lewa_granica..<prawa_granica) Zakres (ang. range) definiujemy używając symboli ”..” lewa_granica..prawa_granica(lewa_granica..prawa_granica)(lewa_granica..<prawa_granica)
Mapy # Przykładowe definicje map def map1= ['id':'FX-11', 'name':'Radish', 'no':1234,] def http = [100 : 'CONTINUE', 200 : 'OK', 400 : 'BAD REQUEST' ] # Istnieje kilka sposobów odwołania się do elementów mapy... assert map1.id == 'FX-17' assert map1['id'] == 'FX-17' assert map1.getAt('id') == 'FX-17‘ assert http[200] == 'OK' #...podobnie jest przy wstawianiu elementów map2.name = 'Potato' map2[-1] = 'washed, but not peeled‘ # Najważniejsze metody assert http.isEmpty() == false assert http.size() == 3 assert http.containsKey(100) assert http.containsValue('OK') assert http.keySet() == toSet([100, 200, 400]) Mapy definiujemy używając symboli [:]def emnpty_map = [:]Ef map [key: value, key: value, key: value] Mapy definiujemy używając symboli [:]def emnpty_map = [:]Ef map [key: value, key: value, key: value]
Instrukcje warunkowe if (false) assert falseif (null){ assert false } else { assert true } switch( a ) {switch ( b ) case 1 : case ~/Gw?+e/: assert false; println "b starts with G!" break case [ 2,3,4 ]: case Date: assert false; println "b is a date„ break case 5..10: default: assert false; break break} } Warunkowe wykonanie instrukcji Instrukcja switch Collection = Collection.grep(filter)
Pętle def i = 0 while (i < 10) { i++ } Assert i = 10 def clinks = 0 for (remainingGuests in 0..9) { clinks += remainingGuests } assert clinks == (10*9)/2 def list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for (j in list) { assert j == list[j] } 5.times { log.info it } Pętla ”while” Pętla ” for ”
def l = [1,2,3] def s = '' list.each { item -> s += item } assert s == '123‘ assert list.any { item -> item < 2 } def d = list.collect { item -> item*2 } assert d == [2,4,6] def odd = list.findAll { i -> i % 2 == 1 } assert odd == [1,3] Przeszukiwanie kolekcji def range = (5..7) r = '' range.each{ e -> r += e } assert r == '567‘ def myMap = [a:1, b:2, c:3] def s = '' myMap.each {e -> s += e.key; s += e.value } assert s.contains('a1b2c3') assert myMap.any { entry -> entry.value > 2 } def d = myMap.collect { entry -> entry.value *= 2 } assert d == [2,4,6] abMap = myMap.findAll { entry -> entry.value < 3} assert abMap.size() == 2 Object.each(Closure) – iteruje poprzez wszystkie elementy iprzekazuje każdy element do zamknięcia List.collect(Closure) – iteruje poprzez wszystkie elementy,przetwarza je a następnie zwraca ich listę Boolean.any(Closure) – iteruje poprzez wszystkie elementy isprawdza czy chociaż jedez elementów spełnia warunek List.findAll(Closure) – iteruje poprzez wszystkie elementy izwraca listę obiektów spełniającyh warunek
XmlParser i MarkupBuilder # Pobieranie danych def langs = new XmlParser().parseText(xml) println "type = ${langs.attribute("type")}" langs.language.each{ println it.text() } # Tworzenie dokumentu def xml = new groovy.xml.MarkupBuilder() xml.langs(type:"current"){ language("Java") language("Groovy") language("JavaScript") } # Tworzenie elementu zokreślonymi atrybutami xml.langs(type:"current", count:3, mainstream:true){ language(flavor:"static", version:"1.5", "Java") } # Odczytywanie atrybutów langs.attributes().each{k,v-> println k println v } Przykładowy dokument XMLDef xml = ””” Java Groovy JavaScript ””” Przykładowy dokument XMLDef xml = ””” Java Groovy JavaScript ”””
GroovySQL import groovy.sql.Sql # Połączenie do bazy sql = Sql.newInstance( connURL, username, password, driverClass ) # Pobieranie i wyświetlanie danych sql.eachRow( 'select * from users' ) { println "$it.id -- ${it.firstname} --" } # Dodawanie danych sql.execute("insert into users (firstName, lastName) values (${fn}, ${ln})") sql.execute('insert into people (firstName, lastName) values (?,?)', [fn,ln]) # Usuwanie danych sql.execute('delete from users where id = ?', [5]) # Modyfikowanie danych sql.executeUpdate('update users set comment = ? where id=002', [comment]) # Przykład wykorzystania MarkupBuilder’a oraz GroovySQL def xml = new MarkupBuilder() sql.eachRow("select * from users != ${ignore}") { user -> xml.customer(id:user.id, type:'USER', name:"$user.firstname $user.lastname" ) }
Wyrażenia regularne twister = 'she sells sea shells at the sea shore of seychelles‘ // =~ creates a Matcher, and in a boolean context, it's "true" if it // has at least one match, "false" otherwise. assert "cheesecheese" =~ /cheese/ assert ! ("cheese" =~ /ham/) // twister must contain a substring of size 3, starts with s and ends with a assert twister =~ /s.a/ // ==~ tests, if String matches the pattern assert "2009" ==~ /\d+/ // returns TRUE assert "holla" ==~ /\d+/ // returns FALSE // twister must contain only words delimited by single spaces assert twister ==~ /(\w+ \w+)*/ assert (twister ==~ /s.e/) == false Groovy opiera się na wyrażeniach regularnych Java jednak dodaje 3operatory, które ułatwiają korzystanie z nich:find operator =~match operator ==~pattern operator ~String Groovy opiera się na wyrażeniach regularnych Java jednak dodaje 3operatory, które ułatwiają korzystanie z nich:find operator =~match operator ==~pattern operator ~String Groovy GStringassert „abc” == /abc/assert „\\d” == /\d/asser „\$” == /$/asser „a\\\\b” == /a\b/ Groovy GStringassert „abc” == /abc/assert „\\d” == /\d/asser „\$” == /$/asser „a\\\\b” == /a\b/
Referencje Groovy API Strona domowa języka Groovy Podręcznik użytkownika Groovy Groovy in Action, Dierk König, Guillaume Laforge, Paul King, Jon Skeet, and Hamlet D'Arcy