On Github Xaerxess / timtowtdi-java-jdd14
Grzegorz Rożniecki (@xaerxess)
Java / Perl / JavaScript developer
Software reader / writer
- Will this talk be about programming languages? Not really. - Java (obviously) - JavaScript (only good parts) - Perl (FTW!) - also: Python (and TIMTOWTDI?) - also: PHP (...) - A bit about good practices and how treat experience from other languages. - Something about good design (**IMO**).There is more than one way to do it
Tim Toady
- Tim Toady - Larry WallThere should be one - and preferably only one - obvious way to do it
- No shortcut for that and no fancy pronounciation - that'll be another way to say the phrase! - vs Perl?for (my $i = 0; $i <= 3; ++$i) { print $i; }- Larry Wall -> linguist
for my $i (0..3) { print $i; }
for (0..3) { print $_; }
for (0..3) { print; }
print for (0..3);- Larry Wall -> linguist
vs
There’s more than one way to do itbut sometimes consistency is not a bad thing either
package Foo; sub new { my $class = shift; my $self = { }; # or [ ] or any arbitrary scalar value return bless $self, $class; } 1;- Perl community lesson: consistency
Inconsistency
TIMTOWTDI?
finally...
but...
final class Person { private final String name; private final Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((age == null) ? 0 : age.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age == null) { if (other.age != null) return false; } else if (!age.equals(other.age)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }vs
case class Person(name: String, age: Int)
Java 7+: Objects Java < 7 - Guava: Objects
@Override public int hashCode() { return Objects.hash(name, age); } @Override public boolean equals(final Object obj) { if (!(obj instanceof Person)) return false; final Person other = (Person) obj; return Objects.equals(this.name, other.name) && Objects.equals(this.age, other.age); }
Better?
Guava 18+: MoreObjects.toStringHelper Guava < 18: Objects.toStringHelper
@Override public String toString() { return MoreObjects.toStringHelper(this) .add("name", name) .add("age", age) .toString(); }
Also better?
@Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; }
Lombok: @Value
@Value public class Person { String name; Integer age; }
Lombok: black magic
Google AutoValue: @AutoValue
@AutoValue abstract class Person { public static Person create(String name, Integer age) { return new AutoValue_Person(name, age); } public abstract String getName(); public abstract int getAge(); }
Good trade-off?
You should prefer List<Foo> over Foo[] whenever possible.
So, why would you ever use object arrays?
Ex. consistent IDE preferences
The "final" battle
...and in 2014 (finally) instead of this:
List<Album> favs = new ArrayList<>(); for (Album a : albums) { boolean hasFavorite = false; for (Track t : a.tracks) { if (t.rating >= 4) { hasFavorite = true; break; } } if (hasFavorite) { favs.add(a); } } Collections.sort(favs, new Comparator<Album>() { @Override public int compare(Album a1, Album a2) { return a1.name.compareTo(a2.name); }});
...you can do this:
List<Album> sortedFavs = albums.stream() .filter(a -> a.tracks.anyMatch(t -> (t.rating >= 4))) .sorted(Comparator.comparing(a -> a.name)) .collect(Collectors.toList());
There is more than one way to do it, finally!
Please send me a feedback:@xaerxess or xaerxess at gmail dot com