Stream etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Stream etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

31 Ekim 2023 Salı

Stream.iterate metodu

iterate metodu - seed + unary operator
İmzası şöyle. Sonsuz bir Stream yaratır. limit() ile sınırlamak gerekir
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
Açıklaması şöyle. Belirtilen seed değerinden başlar ve unary operator ile seed değeri değiştirilir.
Stream iterate(T seed, UnaryOperator<T> f) creates an infinite Stream from iterative application of a function f to an initial element seed.
Bu metod recursive (özyinelemeli veya kendi kendini çağıran) metodların veya döngülerin metodların yerine geçebilir. Bu metod sonsıuz bir Stream yarattığı için limit() ile sınırlandırmak gerekir.

Örnek
Şöyle yaparız.
DoubleStream.iterate(1.0,term -> term*2)
            .limit(n).sum();
Örnek
Şöyle yaparız.
Stream.iterate('a', i -> (char)(i + 1)).limit(26).forEach(System.out::println);
iterate metodu - seed + predicate + unary operator
İmzası şöyle. Predicate ile sınırlanan bir Stream yaratır.
public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, 
  UnaryOperator<T> next)
Java 9 ile geliyor. Belirtilen seed değerinden başlar ve predicate true olduğu müddetçe unary operator ile seed değeri değiştirilir.
Örnek
Şöyle yaparız.
Stream.iterate(exception, Objects::nonNull, Throwable::getCause);
Şu kod ile aynıdır.
Stream.iterate(exception, Throwable::getCause)
      .takeWhile(Objects::nonNull)
Örnek
Belirtilen karakterlerin String içindeki indeksini bulmak için şöyle yaparız.
List<Integer> getIndexList(String word, char c) {
  return IntStream
    .iterate(word.indexOf(c),
             index -> index >= 0,//Predicate
             index -> word.indexOf(c, index + 1))
    .boxed()
    .collect(Collectors.toList());
}

22 Nisan 2023 Cumartesi

Stream.toArray metodu

Giriş
Açıklaması şöyle. toArray(Foo[]::new) şeklinde kullanılır
toArray(): Returns an array containing the elements of the stream.
Örnek
Şöyle yaparız
List<Student> listOfStudents = ...
Student[] arrayOfStudents = students().toArray(Student[]::new);
Örnek
Şöyle yaparız
List<Integer> numbers = ...
Integer[] numberArray = numbers.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(numberArray)); // prints [1, 2, 3, 4, 5]

Stream.skip metodu

Giriş
Not: dropWhile yazısına bakabilirsiniz,  takeWhile yazısına bakabilirsiniz

Açıklaması şöyle.
skip(): Returns a stream with the specified number of elements skipped.
Örnek
Şöyle yaparız
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skippedNumbers = numbers.stream().skip(3).collect(Collectors.toList());
System.out.println(skippedNumbers); // prints [4, 5]
Örnek
Şöyle yaparız.
List<String> tokens = ...;

tokens.stream().skip(1).forEach(token -> ...);

31 Ocak 2023 Salı

Stream.peek metodu - Dikkatli Olmak Lazım

Tüm elemenlar için çağrılır.forEach() ile benzer ancak esas amacı debug içindir. Açıklaması şöyle.
This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline
SonarLint açıklaması şöyle
According to its JavaDocs, the intermediate Stream operation java.util.Stream.peek() “exists mainly to support debugging” purposes.

A key difference with other intermediate Stream operations is that the Stream implementation is free to skip calls to peek() for optimization purpose. This can lead to peek() being unexpectedly called only for some or none of the elements in the Stream.

As a consequence, relying on peek() without careful consideration can lead to error-prone code.
This rule raises an issue for each use of peek() to be sure that it is challenged and validated by the team to be meant for production debugging/logging purposes.
Verilen örnek şöyle
// Noncompliant Code Example
Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e));

// Compliant Solution
Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .foreach(e -> System.out.println("Filtered value: " + e));
Debug
Örnek
Şöyle yaparız.
"abcd".chars().peek(e->System.out.print(e + ":"))
Çıktı olarak şunu alırız.
a:b:c:d:
Örnek
Şöyle yaparız.
Stream.of("one", "two", "three", "four")
  .filter(e -> e.length() > 3)
  .peek(e -> System.out.println("Filtered value: " + e))
  .map(String::toUpperCase)
  .peek(e -> System.out.println("Mapped value: " + e))
  .collect(Collectors.toList());
Setter Çağırmak
Açıklaması şöyle. Yani debug amacı dışında kullanılması yasak değil, ama teşvik te edilmiyor. Dolayısıyla tüm sorumluluk kodlayan kişide.
We can see that non-debugging usages are neither forbidden nor discouraged.
Örnek
Elimizde şöyle bir kod olsun. Burada peek() çağrılıyor. 
// The problem is that this behavior is highly deceiving because certain 
// Stream implementations can optimize out peek() calls.

Stream.of(Date.from(Instant.EPOCH))
  .peek(d -> d.setTime(Long.MAX_VALUE))
  .forEach(System.out::println);

// Sun Aug 17 08:12:55 CET 292278994
Ancak çağrılmadığı durumlar da olabilir. Bazı örnekler şöyle
List.of(1, 2, 3)
  .stream()
  .peek(System.out::println)
  .count();
// The result is empty

Stream.iterate(0, i -> i + 1)
  .peek(System.out::println)
  .findFirst();
// The result is empty
Örnek
Şöyle yaparız.
List<Foo> newFoos = foos.stream()
            .filter(Foo::isBlue)
            .peek(foo -> foo.setTitle("Some value"))
            .collect(Collectors.toList());
Hesap Yapmak
Örnek

Kalan yüzdeyi yazdırmak için kullanılabilir. Şöyle yaparız.
Stream<MyData> myStream = readData();
final AtomicInteger loader = new AtomicInteger();
int fivePercent = elementsCount / 20;
MyResult result = myStream
  .map(row -> process(row))
  .peek(stat -> {
    if (loader.incrementAndGet() % fivePercent == 0) {
      System.out.println(loader.get() + " elements on " + elementsCount + " treated");
      System.out.println((5*(loader.get() / fivePercent)) + "%");
    }
  })
  .reduce(MyStat::aggregate);