Java 8
Java 8 ile gelen lambda expression, functional interface, default methods, stream api, datetime api gibi özelliklerin örnekleri ve kullanımı ile yer alıyor.
Lambda Expression
Lambda expression özelliği daha kısa fonksiyon/metot kullanımını sağlar.
Java 8 öncesinde bir metot tanımlamak için bir OOP özelliği olan arayüz ile yapılıyordu.
public class App {
public static void main(String[] args) {
IToplama toplama = new IToplama() {
@Override
public void topla(int s1, int s2) {
System.out.println(s1 + s2);
}
};
toplama.topla(10, 20);
}
}
interface IToplama {
void topla(int s1, int s2);
}
Metot kullanımı için ilk olarak arayüz ile tanımlanmış ve daha sonra arayüz anonim olarak uygulanmıştır.
Metot tanımlama Lambda expression ile daha sade olarak aşağıdaki hale gelmiştir.
(parametreler) -> { komutlar }
Örnek lambda expression kullanımı aşağıdaki gibidir.
public class App {
public static void main(String[] args) {
IToplama toplama = (int s1, int s2) -> { System.out.println(s1 + s2); };
//IToplama toplama = (int s1, int s2) -> System.out.println(s1 + s2);
//IToplama toplama = (s1, s2) -> System.out.println(s1 + s2);
toplama.topla(10, 20);
}
}
interface IToplama {
void topla(int s1, int s2);
}
Lambda ifadeleri özelliği ile döngü, filtreleme, görsel olaylar (UI events) ve karşılaştırma işlemlerinin yazıımı kısalmıştır.
FunctionalInterface
Lambda expression için oluşturulan arayüzlerde tek metot tanımı yer alır.
Tek metot tanımı olan arayüzler Functional interfaces olarak adlandırılarak diğer arayüzler arasında tanım olarak ayrım yapılmıştır.
Fonksiyonel arayüzleri ifade etmek için @FunctionalInterface annotations kullanılır.
Annotations hakkında detaylı bilgi için Java Annotations yazıma bakmalısın.
public class App {
public static void main(String[] args) {
IToplama toplama = (s1, s2) -> System.out.println(s1 + s2);
toplama.topla(10, 20);
}
}
@FunctionalInterface
interface IToplama {
void topla(int s1, int s2);
}
@FunctionalInterface anahtar kelimesi ile arayüzün bir fonksiyonel arayüz olduğunu belirtmiş olduk.
Java 8, Lamda expression kullanımı için BiConsumer<T,U>, Consumer<T>, Function<T,R> , Predicate<T> gibi ön tanımlı Functional Interfaces tanımları gelir.
Ön tanımlı arayüzler generic programlamaya göre hazırlandığından tür bağımsız olarak çalışır.
Bu sayede yeni arayüz tanımına ihtiyaç kalmadan bir çok metot tanımı yapılabilir.
Default Methods
Arayüzlere içeriği olan varsayılan-default metot eklemek için Java 8 ile programlama diline eklenen özelliktir.
public class App {
public static void main(String[] args) {
ITopla toplama = (s1, s2) -> System.out.println(s1 + s2);
toplama.topla(10, 20);
toplama.yazdir();
}
interface ITopla {
default void yazdir() {
System.out.println("Yusuf Sezer");
}
void topla(int s1, int s2);
}
}
Özellik Java Collection Iterable arayüzü gibi bir çok Java arayüzünde kullanılmaktadır.
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
Özellik sayesinde koleksiyonlar forEach metodunu kullanabilmektedir.
public class App {
public static void main(String[] args) {
List<String> myNames = Arrays.asList("Yusuf", "Sefa", "Sezer");
myNames.forEach((t) -> System.out.println(t + " -> " + t.length()));
}
}
Stream API
Stream veya akım Linux işletim sistemi, .NET IO ve Java IO sınıflarında yer alan ve art arda işlemler için kullanılmaktadır.
Java 8 ile birlikte gelen Stream API fonksiyonel programlama yaklaşımına göre koleksiyon, dizi gibi veriler üzerinde filtreleme, döngü, dönüştürme, dönüşüm gibi işlemler yapmayı sağlar.
public class App {
public static void main(String[] args) {
// Döngü
Stream
.of("Yusuf", "Sefa", "Sezer")
.forEach(System.out::println);
// Mapleme
Stream
.of("Yusuf", "Sefa", "Sezer")
.map(String::toUpperCase)
.forEach(System.out::println);
// Filtreleme
Stream
.of("Yusuf", "Sefa", "Sezer")
.filter(p -> p.startsWith("Y"))
.forEach(System.out::println);
// IntStream
IntStream
.range(0, 10)
.filter(p -> p % 2 == 0)
.forEach(System.out::println);
}
}
Stream API sayesinde döngü, mapleme, filtreleme gibi işlemler için kod ve özel metot yazımına gerek kalmadan yapabildik.
Date-Time API
Java içerisinde tarih-saat işlemleri Date sınıfı ile yapılıyordu.
Date sınıfı ile oluşturulan Tarih/Saat değeri setXXX metotları ile değiştirilebiliyordu.
Tarih/Saat değişimine imkan verdiği için Thread-safe özelliğine sahip değildi.
Ayrıca saat dilimi/time zone gibi bir desteğe sahip değildi.
Java 8 ile birlikte Tarih/Saat işlemleri için geniş sınıf, metot ve numaralandırıcı desteği java.time paketi ile eklenmiştir.
Paket içerisinde JSR 310 şartnamesi ile belirlenen LocalDate, LocalTime, LocalDateTime, ZoneId, ZonedDateTime gibi sınıflar ve Month, DayOfWeek gibi numaralandırıcılar yer alıyor.
public class App {
public static void main(String[] args) {
System.out.println(LocalDate.now());
System.out.println(LocalTime.now());
System.out.println(LocalDateTime.now());
ZoneId.getAvailableZoneIds().forEach(System.out::println);
System.out.println(ZonedDateTime.now(ZoneId.of("Asia/Tokyo")));
System.out.println(ZonedDateTime.now());
System.out.println(OffsetTime.now());
System.out.println(OffsetDateTime.now());
}
}
Belirli bir tarih belirlemek için of metotları, String türünden tarihi çevirmek için parse metotları kullanılır.
Date-Time API sınıflarında yer alan plusXXX, minusXXX metotları ile tarih ve saat ekleme işlemi yapılarak yeni bir nesne elde edilir.
Metot yeni bir nesne oluşturduğundan dolayı thread-safe özelliği sağlanır.
Annotations
Java annotation hakkında detaylı bilgi için annotations yazıma bakmanda fayda var.
Java 8 ile birlikte sınıf, metot gibi alanlarda birden fazla annotation kullama özelliği gelmiştir.
public class App {
public static void main(String[] args) {
}
@Deprecated
@SuppressWarnings(value = "deprecated")
public void eskiMetot() {
System.out.println("www.yusufsezer.com.tr");
}
}
Method Reference
Java 8 ile birlikte metotlar parametre olarak kullanılabilir hale gelmiştir.
Metotları parametre olarak metotlara geçirmek için sınıf::metotAdi kullanılır.
public class App {
public static void main(String[] args) {
IntStream
.range(0, 100)
.reduce(Math::max)
.ifPresent(System.out::println);
}
}
Optional
Java 8 öncesi null istisna yönetimi yapılarak NullPointerException istisnasının yönetimi sağlanıyordu.
null yönetimi beraberinde kodların uzamasına, null yönetimini kontrol edilmediğinde beklenmedik hataların oluşmasına neden oluyordu.
Guava içerisinde yer alan Optional özelliği Java 8 ile birlikte Java programlama diline eklenmiştir.
Bu sayede null yönetimi daha kolay yönetilebilir hale gelmiştir.
public class App {
public static void main(String[] args) {
String name = "Yusuf Sezer";
if (name != null) {
System.out.println(name);
}
Optional.of(name).ifPresent(System.out::println);
}
}
Diğer
Lambda Expression, Stream API ve DateTime API Java 8 ile gelen önemli özelliklerdendir.
Lambda ve Stream özelliği ile Java fonksiyonel programlama yöntemine göre geliştirme özelliği kazanmıştır.
Java fonksiyonel programlama ile uzun ve tekrar eden kodlamayı en aza indirmektedir.
Java 8 ile ayrıca StringJoiner, Base64, Collectors, CompletableFuture sınıfları eklenmiş ve Java IO, Java JDBC gibi paketlere yeni metotlar eklenmiştir.
Yeni gelen özellikler az kod ile daha fazla iş yapmayı sağlamıştır.
Java Derslerine buradan ulaşabilirsiniz.
Hayırlı günler dilerim.