SlideShare a Scribd company logo
Effective Java
with Groovy & Kotlin
How Languages Influence Adoption of
Good Practices
Naresha K

@naresha_k

https://blog.nareshak.com/
About me
Developer, Architect & Coach
Founder & Organiser
Bangalore Groovy User Group
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
http://groovy-lang.org/
initial idea was to make a little
dynamic language which compiles
directly to Java classes and provides
all the nice (alleged) productivity
benefits
- James Strachan
http://radio-weblogs.com/0112098/2003/08/29.html
https://kotlinlang.org/
https://kotlinlang.org/
http://commons.wikimedia.org/wiki/File:You-Are-Here-Earth.png
http://commons.wikimedia.org/wiki/File:You-Are-Here-Earth.png
http://upload.wikimedia.org/wikipedia/commons/4/41/Just_ask_%26_You_are_here_-.jpg
Know your guides
Context/ the Problem
What does “Effective Java” say?
The traps
Idiomatic Solution
Lessons Learned
Tool Wisdom
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
class Product {
String sku
String description
BigDecimal price
}
Product book1 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
Product book2 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
println book1 == book2
false
Product book1 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
Product book2 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
def stock = [:]
stock[book1] = 100
println stock[book2]
null
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
#10: Obey the general contract when
overriding equals
#11: Always override hashCode when
you override equals
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
class Product {
String sku
String description
BigDecimal price
}
class Product {
String sku
String description
BigDecimal price
LocalDate dateOfManufacture
} class Product {
String sku
String description
BigDecimal price
LocalDate dateOfManufacture
LocalDate dateOfExpiry
}
@EqualsAndHashCode
class Product {
String sku
String description
BigDecimal price
}
Product book1 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
Product book2 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
println book1 == book2
true
Product book1 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
Product book2 = new Product(
sku: 'P101',
description: 'Effective Java’,
price: 40.0)
def stock = [:]
stock[book1] = 100
println stock[book2]
100
@EqualsAndHashCode(includes = 'id')
class Product {
Long id
String sku
String description
BigDecimal price
}
@EqualsAndHashCode(includes = 'id')
class Product {
Long id
String sku
String description
BigDecimal price
}
@EqualsAndHashCode(includes = ‘sku')
class Product {
Long id
String sku
String description
BigDecimal price
}
class Product(val sku: String, val description: String,
val price: BigDecimal)
fun main() {
val book1 = Product("P101", "Effective Java", BigDecimal("35.08"))
val book2 = Product("P101", "Effective Java", BigDecimal("35.08"))
println(book1 == book2)
val stock = mapOf(book1 to 100)
println(stock[book2])
}
false
null
data class Product(val sku: String, val description: String, val price:
BigDecimal)
fun main() {
val book1 = Product("P101", "Effective Java", BigDecimal("35.08"))
val book2 = Product("P101", "Effective Java", BigDecimal("35.08"))
println(book1 == book2)
val stock = mapOf(book1 to 100)
println(stock[book2])
}
true
100
data class Product(val sku: String, val description: String,
val price: BigDecimal, var id: Long?)
fun main() {
val book1 = Product("P101", "Effective Java", BigDecimal("35.08"), null)
val book2 = Product("P101", "Effective Java", BigDecimal("35.08"), 1L)
println(book1 == book2)
val stock = mapOf(book1 to 100)
println(stock[book2])
}
false
null
data class Product(val sku: String, val description: String, val price:
BigDecimal) {
var id: Long? = null
}
fun main() {
val book1 = Product("P101", "Effective Java", BigDecimal("35.08"))
val book2 = Product("P101", "Effective Java", BigDecimal("35.08"))
book2.id = 1L
println(book1 == book2)
val stock = mapOf(book1 to 100)
println(stock[book2])
}
true
100
AST Transformation
Single point of representation
of any knowledge
Language / Compiler
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
#58: Prefer for-each loops to
traditional for loops
def numbers = [10, 20, 30, 40]
def sum = 0
for(int number in numbers){
sum += number
}
println "Sum: " + sum
numbers.each { number ->
println number
}
println numbers.collect { number ->
number * 2
}
println numbers.inject(0,
{ result, number -> result + number }
)
10
20
30
40
[20, 40, 60, 80]
100
numbers.forEach {
println(it)
}
println(numbers.map {
it * 2
})
println(numbers.fold(0)
{ acc, number -> acc + number })
10
20
30
40
[20, 40, 60, 80]
100
Closures/ Higher Order Functions
Favor Internal iterators to
external iterators
Minimise the moving parts
float price = 0.1f;
float total = 0;
for(int i=0; i<10; i++){
total += price;
}
System.out.println("Total: " + total);
Total: 1.0000001
double price = 0.1;
double total = 0;
for(int i=0; i<10; i++){
total += price;
}
System.out.println("Total: " + total);
Total: 0.9999999999999999
#60: Avoid float and double if exact
answers are required
BigDecimal price = new BigDecimal(0.1);
BigDecimal total = new BigDecimal(0);
for(int i=0; i<10; i++){
total = total.add(price);
}
System.out.println("Total: " + total);
Total: 1.0000000000000000555111512312578270211815834045410156250
BigDecimal price = new BigDecimal(0.1);
BigDecimal total = new BigDecimal(0);
for(int i=0; i<10; i++){
total = total.add(price);
}
System.out.println("Total: " + total);
Total: 1.0000000000000000555111512312578270211815834045410156250
def price = 0.1
def total = 0
for(int i=0; i<10; i++){
total += price
}
println "Total: " + total
Total: 1.0
def price = 0.1
def total = 0
for(int i=0; i<10; i++){
total += price
}
println "Total: " + total
println price.class
println total.class
Total: 1.0
class java.math.BigDecimal
class java.math.BigDecimal
Select appropriate defaults
Principle of Least Astonishment
Million Dollar Effort
Million Dollar Effort
null check
List<Speaker> getSpeakers(String conference) {
return null;
}
List<Speaker> j2DaysSpeakers = getSpeakers("Java2Days-2019");
if (j2DaysSpeakers != null) {
//...
}
#54: Return empty arrays or
collections, not nulls
println getSpeakers('Java2Days-2019')
.collect { it.firstName }
println getSpeakers('Java2Days-2019')
.findAll { it.firstName.length() > 5 }
println getSpeakers('Java2Days-2019')
.collect { it.firstName } // []
println getSpeakers('Java2Days-2019')
.findAll { it.firstName.length() > 5 } // []
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
fun getSpeakers(conference: String): List<Speaker> {
return null
}
fun getSpeakers(conference: String): List<Speaker> {
return null
}
Null can not be a value of a non-null type List<Speaker>
fun getSpeakers(conference: String): List<Speaker> {
return null
}
Null can not be a value of a non-null type List<Speaker>
fun getSpeakers(conference: String): List<Speaker>? {
return null
}
NullObject Pattern
No boilerplate code - $$$
Life is too short for null checks!
Type system
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
#3: Enforce the singleton property
with a private constructor
or an enum type
class Manager {
private static final Manager manager =
new Manager()
private Manager() { super() }
static Manager getInstance() { manager }
}
def m1 = Manager.getInstance()
def m2 = Manager.getInstance()
println m1 == m2
true
class Manager {
private static final Manager manager =
new Manager()
private Manager() { super() }
static Manager getInstance() { manager }
}
def m1 = Manager.getInstance()
def m2 = Manager.getInstance()
println m1 == m2
true
def m3 = new Manager()
println m3 Manager@b968a76
@Singleton
class Manager {}
def m1 = Manager.getInstance()
def m2 = Manager.getInstance()
println m1 == m2
def m3 = new Manager()
println m3
true
Caught: java.lang.RuntimeException: Can't instantiate singleton Manager.
Use Manager.instance
object Manager {
init {
println("Initialising Manager")
}
}
public final class Manager {
public static final Manager INSTANCE;
private Manager() {
}
static {
Manager var0 = new Manager();
INSTANCE = var0;
String var1 = "Initialising Manager";
boolean var2 = false;
System.out.println(var1);
}
}
private static Manager manager
static Manager getInstance() {
if(!manager){ manager = new Manager() }
manager
}
private static Manager manager
static synchronized Manager getInstance() {
if(!manager){ manager = new Manager() }
manager
}
private static volatile Manager manager
static synchronized Manager getInstance() {
if(!manager){ manager = new Manager() }
manager
}
@Singleton(lazy=true)
class Manager {}
public static Manager getInstance() {
if (instance != null) {
return instance
} else {
synchronized (Manager) {
if (instance != null) {
return instance
} else {
return instance = new Manager()
}
}
}
}
AST Transformation
YAGNI
Premature optimisation is the root
of all evil
Object Declaration
https://www.flickr.com/photos/38080114@N07/8594601982/
#17: Minimize Mutability
Rules to make a class immutable
1. Don’t provide any mutators
2. Ensure that the class can’t be extended
3. Make all fields final
4. Make all fields private
5. Ensure exclusive access to any mutable
components
class ImmutableClass{
private final def field1
private final def field2
//...
private final def field10
public ImmutableClass(f1, f2,… f10){
//initialization
}
}
import groovy.transform.Immutable
@Immutable
class Rectangle {
int length
int breadth
}
def r = new Rectangle(length: 10, breadth: 5)
println r // Rectangle(10, 5)
public final class Rectangle extends java.lang.Object
implements groovy.lang.GroovyObject {
private final int length
private final int breadth
public Rectangle(int length, int breadth) {
//
}
public Rectangle(java.util.Map args) {
}
public Rectangle() {
this([:])
}
}
new Rectangle(length: 10, breadth: 5)
data class Rectangle(val length: Int, val breadth: Int)
public final class Rectangle {
private final int length;
private final int breadth;
public final int getLength() {
return this.length;
}
public final int getBreadth() {
return this.breadth;
}
public Rectangle(int length, int breadth) {
this.length = length;
this.breadth = breadth;
}
// more code
}
data class Rectangle(val length: Int, val breadth: Int)
fun main() {
val rectangle = Rectangle(20, 10)
val r2 = Rectangle(length = 20, breadth = 10)
}
public static final void main() {
Rectangle rectangle = new Rectangle(20, 10);
Rectangle r2 = new Rectangle(20, 10);
}
AST Transformation
Readability Matters
Syntactic Sugar
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices
#18: Favour composition over
inheritance
def ph = ['919812312345', '4512341234', ‘19252199916']
as PhoneNumbers
println ph.find { it == '19252199916'}
println ph.findAll { it.endsWith('4') }
def ph = ['919812312345', '4512341234', '19252199916']
as PhoneNumbers
println ph.find { it == '19252199916'}
println ph.findAll { it.endsWith('4') }
println ph.indianNumbers()
class PhoneNumbers extends ArrayList {
}
class PhoneNumbers {
private @Delegate List phoneNumbers
PhoneNumbers(numbers) {
phoneNumbers = numbers
}
def indianNumbers() {
phoneNumbers.findAll { it.startsWith('91') }
}
}
class PhoneNumbers(val list: List<String>) :
List<String> by list {
fun indianNumbers(): List<String> {
return list.filter { it.startsWith("91") }
}
}
trait CanSing {
def sing() {
println "Singing"
}
}
trait CanDance {
def dance() {
println "Dancing"
}
}
class Person implements CanSing, CanDance {}
Person reema = new Person()
reema.sing()
reema.dance()
https://www.slideshare.net/nareshak/designing-with-groovy-traits-gr8conf-india
AST Transformation
Simplify
Take Aways
Some of the ‘Effective Java’ already
built into the languages
Favour compiler generated cod to
IDE generated code
Don’t fall into the trap of copying the
Java implementation
Programming languages can reduce
friction to implement good practices
There could be multiple right
solutions. Choose what fits your
context
The way we code is influenced not
just by the language we code in,
but also by the languages we
know.
Happy Coding. Thank You

More Related Content

What's hot (18)

PDF
C# Advanced L02-Operator Overloading+Indexers+UD Conversion
Mohammad Shaker
 
PDF
Javaslang @ Devoxx
David Schmitz
 
PDF
Advanced java practical semester 6_computer science
Niraj Bharambe
 
KEY
Gwt and Xtend
Sven Efftinge
 
PPT
Scala introduction
Yardena Meymann
 
PDF
Guice2.0
Masaaki Yonebayashi
 
PDF
Auto-GWT : Better GWT Programming with Xtend
Sven Efftinge
 
ODP
Concurrency on the JVM
Vaclav Pech
 
PDF
How and why I turned my old Java projects into a first-class serverless compo...
Mario Fusco
 
PPT
"Scala in Goozy", Alexey Zlobin
Vasil Remeniuk
 
PDF
Scala in practice
andyrobinson8
 
PPTX
Open sourcing the store
Mike Nakhimovich
 
PPTX
Reactive programming every day
Vadym Khondar
 
PPTX
All about scala
Yardena Meymann
 
PPT
Swiss army knife Spring
Mario Fusco
 
ODP
Pick up the low-hanging concurrency fruit
Vaclav Pech
 
PDF
How to implement g rpc services in nodejs
Katy Slemon
 
PDF
Anonymous functions in JavaScript
Mohammed Sazid Al Rashid
 
C# Advanced L02-Operator Overloading+Indexers+UD Conversion
Mohammad Shaker
 
Javaslang @ Devoxx
David Schmitz
 
Advanced java practical semester 6_computer science
Niraj Bharambe
 
Gwt and Xtend
Sven Efftinge
 
Scala introduction
Yardena Meymann
 
Auto-GWT : Better GWT Programming with Xtend
Sven Efftinge
 
Concurrency on the JVM
Vaclav Pech
 
How and why I turned my old Java projects into a first-class serverless compo...
Mario Fusco
 
"Scala in Goozy", Alexey Zlobin
Vasil Remeniuk
 
Scala in practice
andyrobinson8
 
Open sourcing the store
Mike Nakhimovich
 
Reactive programming every day
Vadym Khondar
 
All about scala
Yardena Meymann
 
Swiss army knife Spring
Mario Fusco
 
Pick up the low-hanging concurrency fruit
Vaclav Pech
 
How to implement g rpc services in nodejs
Katy Slemon
 
Anonymous functions in JavaScript
Mohammed Sazid Al Rashid
 

Similar to Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices (20)

PDF
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Naresha K
 
PDF
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Naresha K
 
PDF
Effective Java with Groovy
Naresha K
 
PDF
Effective Java with Groovy - How Language can Influence Good Practices
Naresha K
 
PPTX
Benefits of Kotlin
Benjamin Waye
 
PPTX
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Matthew Farwell
 
PDF
Bologna Developer Zone - About Kotlin
Marco Vasapollo
 
PPTX
Joy of scala
Maxim Novak
 
PDF
What's in Groovy for Functional Programming
Naresha K
 
PDF
Google Guava - Core libraries for Java & Android
Jordi Gerona
 
PPTX
Stop that!
Doug Sparling
 
PPTX
Hello kotlin | An Event by DSC Unideb
Muhammad Raza
 
PDF
Java beginners meetup: Introduction to class and application design
Patrick Kostjens
 
PDF
Clean code
Arturo Herrero
 
PPTX
KotlinForJavaDevelopers-UJUG.pptx
Ian Robertson
 
PDF
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kirill Rozov
 
KEY
ddd+scala
潤一 加藤
 
PDF
An Introduction to Scala (2014)
William Narmontas
 
PPTX
Kotlin
YeldosTanikin
 
PDF
Scala for Java Developers (Silicon Valley Code Camp 13)
Ramnivas Laddad
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Naresha K
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Naresha K
 
Effective Java with Groovy
Naresha K
 
Effective Java with Groovy - How Language can Influence Good Practices
Naresha K
 
Benefits of Kotlin
Benjamin Waye
 
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Matthew Farwell
 
Bologna Developer Zone - About Kotlin
Marco Vasapollo
 
Joy of scala
Maxim Novak
 
What's in Groovy for Functional Programming
Naresha K
 
Google Guava - Core libraries for Java & Android
Jordi Gerona
 
Stop that!
Doug Sparling
 
Hello kotlin | An Event by DSC Unideb
Muhammad Raza
 
Java beginners meetup: Introduction to class and application design
Patrick Kostjens
 
Clean code
Arturo Herrero
 
KotlinForJavaDevelopers-UJUG.pptx
Ian Robertson
 
Kotlin Basics - Apalon Kotlin Sprint Part 2
Kirill Rozov
 
ddd+scala
潤一 加藤
 
An Introduction to Scala (2014)
William Narmontas
 
Scala for Java Developers (Silicon Valley Code Camp 13)
Ramnivas Laddad
 
Ad

More from Naresha K (20)

PDF
The Groovy Way of Testing with Spock
Naresha K
 
PDF
Evolving with Java - How to Remain Effective
Naresha K
 
PDF
Take Control of your Integration Testing with TestContainers
Naresha K
 
PDF
Implementing Resilience with Micronaut
Naresha K
 
PDF
Take Control of your Integration Testing with TestContainers
Naresha K
 
PDF
Favouring Composition - The Groovy Way
Naresha K
 
PDF
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Naresha K
 
PDF
Implementing Cloud-Native Architectural Patterns with Micronaut
Naresha K
 
PDF
Groovy - Why and Where?
Naresha K
 
PDF
Leveraging Micronaut on AWS Lambda
Naresha K
 
PDF
Groovy Refactoring Patterns
Naresha K
 
PDF
Implementing Cloud-native Architectural Patterns with Micronaut
Naresha K
 
PDF
Evolving with Java - How to remain Relevant and Effective
Naresha K
 
PDF
Beyond Lambdas & Streams - Functional Fluency in Java
Naresha K
 
PDF
GORM - The polyglot data access toolkit
Naresha K
 
PDF
Rethinking HTTP Apps using Ratpack
Naresha K
 
PDF
Design Patterns from 10K feet
Naresha K
 
PDF
Java beyond Java - from the language to platform
Naresha K
 
PDF
Think beyond frameworks, The real gems are in the languages
Naresha K
 
PDF
Designing with Groovy Traits - Gr8Conf India
Naresha K
 
The Groovy Way of Testing with Spock
Naresha K
 
Evolving with Java - How to Remain Effective
Naresha K
 
Take Control of your Integration Testing with TestContainers
Naresha K
 
Implementing Resilience with Micronaut
Naresha K
 
Take Control of your Integration Testing with TestContainers
Naresha K
 
Favouring Composition - The Groovy Way
Naresha K
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Naresha K
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Naresha K
 
Groovy - Why and Where?
Naresha K
 
Leveraging Micronaut on AWS Lambda
Naresha K
 
Groovy Refactoring Patterns
Naresha K
 
Implementing Cloud-native Architectural Patterns with Micronaut
Naresha K
 
Evolving with Java - How to remain Relevant and Effective
Naresha K
 
Beyond Lambdas & Streams - Functional Fluency in Java
Naresha K
 
GORM - The polyglot data access toolkit
Naresha K
 
Rethinking HTTP Apps using Ratpack
Naresha K
 
Design Patterns from 10K feet
Naresha K
 
Java beyond Java - from the language to platform
Naresha K
 
Think beyond frameworks, The real gems are in the languages
Naresha K
 
Designing with Groovy Traits - Gr8Conf India
Naresha K
 
Ad

Recently uploaded (20)

PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PDF
Driver Easy Pro 6.1.1 Crack Licensce key 2025 FREE
utfefguu
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PDF
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Driver Easy Pro 6.1.1 Crack Licensce key 2025 FREE
utfefguu
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 

Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good Practices