31 Mayıs 2017 Çarşamba

Consumer Arayüzü

Giriş
Şu satırı dahil ederiz.
import java.util.function.Consumer;
Consumer verilen nesne ile bir işlem yapar ve void döner. IntConsumer, DoubleConsumer gibi özelleşmiş halleri vardır.

Consumer genellikle forEach () ile kullanılır. Ekrana sadece nesneyi basan bir consumer için şöyle yaparız
public class Main {
  public static void main(String[] args) {
    Consumer<Boolean> myConsumer = b -> System.out.println("b = " + b);

    Stream.of("aa", "bb", "cc")
      .map(Main::myBooleanFunction)
      .forEach(myConsumer);

  }

  static boolean myBooleanFunction(String s) {
    return s.startsWith("b");
  }
}
accept metodu
Consumer arayüzünden kalıtıp ayrı bir sınıf yazmak yerine lambda kullanmak çok daha kolay. Ancak yine de eski tarzda yapmak istersek şŞöyle yaparız.
class PrintConsumer implements Consumer<String> {

  @Override
  public void accept(String bar) {
   ...
  }
}
andThen metodu
Consumer arayüzünün böyle bir metodu var. Consumer nesnesine geçilen elemanı andThen metodunu çağırarak bir daha işler. Şöyle yaparız.
Consumer<Integer> cons = in -> ...;
cons.andThen(in ->...)

CompletableFuture Sınıfı

Giriş
Sınıf şöyledir. T parametresi döndürülen tiptir. Bu sınıfta çok fazla metod var !
CompletableFuture<T> implements CompletionStage<T>, implements Future<T>
constructor
Şöyle yaparız.
CompletableFuture<String> f = new CompletableFuture<>();
complete metodu
Şöyle yaparız.
CompletableFuture<String> f = new CompletableFuture<>();
f.complete (...);
completedFuture metodu - static
Completed nesne döner. isDone () metodu true olur. Şöyle yaparız.
List<String> userList = ...
CompletableFuture<List<String>> f = CompletableFuture.completedFuture(userList);
join metodu
Future arayüzündeki get() metoduna benzer bir kullanım sağlar. Farklı olarak unchecked exception fırlatabilir. Böylece try-catch yazmak zorunda kalmayız.

getNow metodu
Future arayüzündeki get() metoduna benzer bir kullanım sağlar. Farklı olarak hemen döner.

thenApply metodu
Future nesnesinin döndürdüğü tipi bir baka tipe çevirir. Şöyle yaparız.
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> "1234");
CompletableFuture<Integer> theNumber = f.thenApply(Integer::parseInt);
System.out.println(theNumber.get());
X döndüren bir future nesnesini void döndüren hale getirmek için şöyle yaparız.
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
  return realChannel.write(engineToSocketData).<Void> thenApply(c -> null);
}
veya şöyle yaparız.
public CompletableFuture<Void> packetEncrypted(ByteBuffer engineToSocketData) {
  return realChannel.write(engineToSocketData).thenApply(c -> (Void) null);
}
runAsync metodu - Runnable
static Factory metodudur. Runnable sonuç dönmeyeceği için dönüş tipi void olur. Metodun imzası şöyle
CompletableFuture<Void> runAsync (Runnable runnable) 
runAsync metodu - Runnable + Executor
static Factory metodudur. Runnable sonuç dönmeyeceği için dönüş tipi void olur. Örnek ver

supplyAsync metodu - Supplier
static Factory metodudur. Supplier sonuç döneceği için dönüş tipi vardır. ExecutorService.submit metodunu çağırmak gibidir yani işi çalıştırılması için bir ThreadPool'a teslim eder. Metodun imzası şöyle
CompletableFuture<U> supplyAsync(Supplier<U> supplier)
Şöyle yaparız.
CompletableFuture<String> f = CompletableFuture.supplyAsync(() -> "1234");
supplyAsync metodu - Supplier + Executor
static Factory metodudur. Supplier sonuç döneceği için dönüş tipi vardır. ExecutorService.submit metodunu çağırmak gibidir yani işi çalıştırılması için bir ThreadPool'a teslim eder. Örnek ver

thenAccept metodu
CompletableFuture nesnesini çalıştıran thread tarafından çağrılır.

thenCompose metodu
Şöyle yaparız.
CompletionStage<List<String>> cacheFuture = ...;

return cacheFuture.thenCompose((List<String> userList) -> {
  ...
})
toCompletableFuture metodu
Şöyle yaparız.
CompletionStage<List<String>> cacheFuture = ...;

return cacheFuture.thenCompose((List<String> userList) -> {
  ...
}).toCompletableFuture(); //convert `CompletionStage` to `CompletableFuture`




30 Mayıs 2017 Salı

PBEKeySpec Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.security.spec.KeySpec;
import javax.crypto.spec.PBEKeySpec;
Açıklaması şöyle
In general cryptographic hashes such as MD5, SHA-1 or SHA-512 should not be used to directly hash a password. A password hash or PBKDF should be used. Examples are PBKDF2, bcrypt, scrypt and Argon2. These functions also take a salt and work factor to provide additional protection.
Cryptographic hash algoritmalarını direkt kullanmanın zararı ile ilgili bir diğer açıklama ise şöyle
The length of the password is limited by the length of the cypher() encryption algorithm. For instance, AES128 takes a 16-byte key. That means that your scheme couldn't accept passwords longer than 16 bytes, if we used AES128 encryption as cypher(). That's generally a bad idea -- artificial restrictions on the length of the password can only harm security.
Açıklaması şöyle. Bu sınıf AES gibi symmetric şifrelemelerde kullanılıyor.
Password hash algorithms have been invented for safe password hashing, also known as password based key derivation functions (PBKDF). The difference between a password hash and a PBKDF is mainly how the result is used: directly as a password hash to compare with a stored password hash or as symmetric key for input in a symmetric cipher or MAC algorithm.

Well known password hash algorithms are PBKDF2, bcrypt, scrypt and of course the already mentioned Argon2. The latter two also contain options for configuring memory hardness, to overcome hardware based attacks.
Bu sınıf altta SHA-1 kullanıyor. Açıklaması şöyle
The functions can often be configured using a hash function. For instance PBKDF2 requires a secure hash as configuration parameter, and it (kinda) defaults to SHA-1.
Kullanım
PBKDF2 (Password-Based Key Derivation Function 2) algoritmasını gerçekleştirir. Şöyle yaparız.
SecretKeyFactory f = SecretKeyFactory.getInstance("...");
byte[] key = f.generateSecret(spec).getEncoded();
constructor - password + salt + iterationCount
Şöyle yaparız.
byte[] salt = { ... };
String passPhrase = ...;
int iterationCount = 2;
KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
constructor - password + salt + iterationCount + keyLength
AES için şöyle yaparız.
PBEKeySpec spec = new PBEKeySpec("password", "salt".getBytes(),1000  , 128);

Double Sınıfı

parse metodu - string
Şöyle yaparız.
String str = ...;
try {
  double d = Double.parseDouble(str);
} catch(NumberFormatException nfe) {
  ...
}
Bilimsel yani scientific gösterim şöyledir.
3564e-8 //returns 0.00003564
Örnek
Scientific notation ile belirtilen bir string'i parse edebilir. Şöyle yaparız.
double d = Double.parseDouble("4.30000000e01");
Örnek
Şöyle yaparız.
double d = Double.valueOf("4.30000000e+01");

Method Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.lang.reflect.Method;
constructor - Class.getDeclaredMethod metodu
Access modifier tipine bakmaksızın nesnenin tanımladığı - kalıtımla gelen hariç - ismi belirtilen metodu döner.

Örnek 1
Elimizde şöyle bir sınıf olsun. Erişmek istediğiniz metod public.
public class Foo {
  public void isFoo(Object obj) {
    ...
  }
}
Bir parametre alan metodu bulmak için şöyle yaparız.
Class c = Foo.class;
Method m = c.getDeclaredMethod("isFoo", Object.class);
Metodumuz birden çok parametre alsaydı ikinci parametreyi bir dizi olarak geçebilirdik.
String methodName = ...;
Class[] types = ...;
Method method = c.getDeclaredMethod(methodName, types);
Örnek 2
Elimizde şöyle bir sınıf olsun. Bu sefer erişmek istediğimiz metod protected.
public class PrivateCar {

  private String color;

  protected void drive() {
    System.out.println("this is private car! the color is:" + color);
  }
}
Şöyle yaparız.
Class clazz = loader.loadClass("javaReflect.test.PrivateCar");
Method method = clazz.getDeclaredMethod("drive");
constructor - Class.getDeclaredMethods
Access modifier tipine bakmaksızın nesnenin tanımladığı - kalıtımla gelenler hariç - tüm metodları döner.

Örnek ver.

constructor - Class.getMethod metodu
Elimizde şöyle bir sınıf olsun.
class Foo {
  public void foo() {
  }
}
Şöyle yaparız.
Method m = c.getMethod("foo");
Eğer foo int parametresi alıyor olsaydı şöyle yapardık.
Method m = c.getMethod("foo", int.class);
constructor - Class.getMethods metodu
Sadece public metodları döner. Şöyle yaparız.
Method[] methods = c.getMethods();
getAnnotation metodu
Elimizde şöyle bir metod olsun.
@CachePut(value ="DATA1", key = "#key1")
public Object saveData1(long key1, Object obj) {
  ...
}
Bu metodun Annotation değerlerine erişmek için şöyle yaparız. Tabi CachePut sınıfının elimizde olması gerekir.
Method method = ..;
String[] value = new String[1];

CachePut cachePut = method.getAnnotation(CachePut.class);
if (cachePut != null) {
  value = cachePut.value();
}

getDeclaringClass metodu
Bir metodun override edildiğini anlamak için şöyle yaparız.
class Base {
  public void bar() {}
}
class Derived extends Base {
  @Override   
  public void bar() {}
}
...
Method mbar = Derived.class.getMethod("bar");
boolean ovrBar = mbar.getDeclaringClass() != Base.class;
System.out.println("Have override for bar: "+ovrBar);
Çıktı olarak şunu alırız.
Have override for bar: true
getName metodu
Şöyle yaparız.
Method method = ...;
String name = method.getName();  
getParameterTypes metodu
Şöyle yaparız.
Method method = ...;
Class<?>[] params = method.getParameterTypes();
Parametreleri string'e çevirmek için şöyle yaparız.
String str = "";
for (int i = 0; i < params.length; i++) {
  if (i > 0) {
    str += ", ";
  }
  str += (params[i].getSimpleName());
}
invoke metodu
Şöyle yaparız.
Foo foo = ...;
Object obj = ...;

m.invoke(foo, o2);
Eğer metod parametre almıyorsa, ikinci parametre null geçilebilir.
m.invoke(foo, null);
null Object[]'ye cast edilebilir ancak ben sevmiyorum. Şöyle yaparız.
m.invoke(foo, (Object[]) null);
isBridge metodu
Şöyle yaparız. true ve false döner.
method.isBridge();
setAccessible metodu
Public olmayan metodlara erişebilmemizi sağlar. Şöyle yaparız.
class Dummy{
  private void foo(){
    System.out.println("hello foo()");
  }
}

class Test{
  public static void main(String[] args) throws Exception {
    Dummy d = new Dummy();
    Method m = Dummy.class.getDeclaredMethod("foo");
    //m.invoke(d);// throws java.lang.IllegalAccessException
    m.setAccessible(true);// Abracadabra 
    m.invoke(d);// now its OK
  }
}