30 Kasım 2017 Perşembe

StreamEx

Giriş
StreamEx sınıfı dışında IntStreamEx gibi özelleşmiş sınıflar da var.



joining metodu
Bu metod ile .collect(Collectors.X()) gibi çağrılar yapmaya gerek yok. 

pairMap metodu
Stream'deki yanyan iki nesnesi belirtilen fonksiyona verir.
Örnek
Pair nesnesi oluşturmak için şöyle yaparız.
Stream<Pair> pairs = StreamEx.of(stream).pairMap(Pair::new);
toList metodu
Bu metod ile .collect(Collectors.X()) gibi çağrılar yapmaya gerek yok.

groupingBy metodu
Bu metod ile .collect(Collectors.X()) gibi çağrılar yapmaya gerek yok. 


29 Kasım 2017 Çarşamba

Selector Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
Genellikle bu sınıfı süren yani select() metodunu çağıran 1 veya daha fazla thread bulunur.

Bu sınıfa verilen socket nesnelerinin non-blocking olması gerekir. Yani şöyle yaparız.
ServerSocketChannel serverChannel = ...;
serverChannel.configureBlocking(false);
Channel'dan SelectionKey'e erişmek için şöyle yaparız.
SocketChannel channel = ...;
SelectionKey key = channel.keyFor (selector);
close metodu
Örnek ver

keys metodu
Açıklaması şöyle
"Returns this selector's key set. The key set is not directly modifiable. A key is removed only after it has been cancelled and its channel has been deregistered. Any attempt to modify the key set will cause an UnsupportedOperationException to be thrown. The key set is not thread-safe."
open metodu
Şöyle yaparız.
Selector selector = Selector.open();
select metodu
Genelde bir döngü için şöyle kullanılır. "Ready" olan key sayısını döner. Şöyle yaparız.
while (true) {
  selector.select();

  Set<SelectionKey> keys = selector.selectedKeys();
  for (SelectionKey key : keys) {

    SelectableChannel channel = key.channel();

    if (key.isAcceptable())    {...}
    else if (key.isWritable()) {...}
    else if (key.isReadable()) {...}
    }   
}
selectedKeys metodu
Açıklaması şöyle. selectedKey() her zaman keys() metodunun alt kümesini döndürür.
"Returns this selector's key set. The key set is not directly modifiable. A key is removed only after it has been cancelled and its channel has been deregistered. Any attempt to modify the key set will cause an UnsupportedOperationException to be thrown. The key set is not thread-safe."
Şöyle yaparız. key'ler ile ilgili yapılabilecek işlemker için SelectionKey Sınıfı'na bakınız.
Set readyKeys = selector.selectedKeys();
Iterator it = readyKeys.iterator();  
while (it.hasNext()) {
  SelectionKey key = (SelectionKey )it.next();
  if (key.isReadable()) {
    ...
  }
  it.remove();
}
Döngüdeki remove() çağrısıının açıklaması şöyle
Notice the keyIterator.remove() call at the end of each iteration. The Selector does not remove the SelectionKey instances from the selected key set itself. You have to do this, when you are done processing the channel. The next time the channel becomes "ready" the Selector will add it to the selected key set again.
selectNow metoud
Şöyle yaparız.
Selector selector = ...;

if (selector.selectNow() != 0) {
  ...
}
wakeUp metodu
Selector select() metodu içinde bloke olmuş iken yeni bir SelectableChannel eklenirse,kapatılırsa vs. select() çağrısından çıkarmak için kullanılır.
Örnek ver

Diğer
Gördüğüm bir gerçekleştirimde bu sınıf sarmalanıyordu. Okuma ve yazma işlemi için kuyruklar tutuluyordu.
Map <SocketChannel ,Queue <ByteBuffer>> outgoingData = ...;
ByteBuffer incomingData =...
Gönderilecek veri kuyrupa ekleniyor ve channel için SelectionKey.OP_WRITE işlemi başlatılıyor.
Socket müsait olunca yazma işlemi başlıyor ve tüm veri döngü içinde gönderilmeye çalışılıyor. Yazma işlemi bitince map boş ise SelectionKey.OP_READ başlatılıyor.

Okuma işleminde incomingData temizleniyor ve okuma işlemi yapılıyor. Bu veri daha sonra hemen bir işlenmek üzere bir kuyruğa konuluyor. Kuyruk şöyle
BlockingQueue<NetworkEvent > eventQueue = ...;




DecimalFormat Sınıfı

Giriş
Şu satırı dahil ederiz.
import java.text.DecimalFormat;
Decimal format yerine String.format() ta rahatça kullanılabilir. Şu iki kod aynı işi görür.
String number=String.format("%.7f", 1.234567777);
ile
DecimalFormat df = new DecimalFormat("####0.000000");
String result = df.format(1.234);
System.out.println(result);
aynıdır.

DecimalFormat gösterimsel amaçlı olarak double, BigDecimal gibi sınıfları String'e çevirir. Decimal format NumberFormat sınıfından kalıtır.

DecimalFormat ile para formatlama işleri ile ilgili aldığım notlar aşağıda. Daha detaylı bilgi için Customizing Formats başlıklı yazıya göz atabilirsiniz.
Burada dikkat edilmesi gereken nokta eğer verilen formatlama hassasiyetinden daha fazla küsürat varsa, sayı yuvarlamaya tabi tutulur.
DecimalFormat provides rounding modes defined in RoundingMode for formatting. By default, it uses RoundingMode.HALF_EVEN.
HALF_EVEN yuvarlamada, sayı tam ortadaysa, her zaman çift olan sayıya yuvarlanır.

constructor - String
Şöyle yaparız.
DecimalFormat df = new DecimalFormat("#.##");
constructor - String + DecimalFormatSymbols
DecimalFormatSymbols nesnesi alır. Sisteminkinden farklı bir locale kullanmak istersek şöyle yaparız.
DecimalFormat df = new DecimalFormat("#.##", 
                               DecimalFormatSymbols.getInstance(Locale.ENGLISH));
format metodu
Örnek - double
Şöyle yaparız.
NumberFormat formatter = new DecimalFormat("#0.00");     
System.out.println(formatter.format(4.0));
Örnek - BigDecimal
Şöyle yaparız.
String str = df.format(new BigDecimal(95.1));
getInstance
Belli bir locale kullanan instance alınabilir.
DecimalFormat nf = DecimalFormat.getInstance(Locale.ENGLISH);
setGroupingSize metodu
Formatlama için verilen string yerine aynısı kodla da yapılabilir. Şöyle bir format'ımız olsun.
DecimalFormat df = new DecimalFormat("###,###.00", symbols);
Aynısını kodla şöyle yaparız.
DecimalFormat df = new DecimalFormat();
df.setDecimalFormatSymbols(symbols);
df.setGroupingSize(3);
df.setMaximumFractionDigits(2);
setNegativePrefix metodu
Şöyle yaparız.
df.setNegativePrefix("(");
setNegativeSuffix metodu
Şöyle yaparız.
df.setNegativeSuffix("%)");
setRoundingMode metodu
DecimalFormat sınıfının setRoundingMode() metodu kullanılarak, yuvarlama metodu değiştirilebilir.
1. CEILING
Şöyle yaparız.
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
    Double d = n.doubleValue();
    System.out.println(df.format(d));
}
Çıktı olarak şunu alırım.
12
123.1235
0.23
0.1
12341234.2125
2. FLOOR
Eksi sonsuza doğru yuvarlar. Eksi sayılarda bu açından DOWN'dan farklı sonuç verir. Şöyle yaparız.
df.setRoundingMode(RoundingMode.FLOOR);
3. DOWN
Sıfıra doğru yuvarlar. Eksi sayılarda bu açıdan FLOOR'dan farklı sonuç verir. Şöyle yaparız.
double value = 0.03303;
DecimalFormat df = new DecimalFormat("###.##;-###.##");
df.setRoundingMode(RoundingMode.DOWN);
System.out.println(df.format(value));
Çıktı olarak şunu alırım.
0.03
Formatlamada kullanılan işaretler ve Kullanım Şekilleri
Formatlamada en çok # işareti kullanılıyor. # kaç tane hane istendiğini belirtir. Sayı istenilen haneden fazlasına sahipse, yuvarlamaya tabi tutulur. Eğer istenilen haneden azına sahipse, # karakteri yerine bir şey yazılmaz!
# işareti ile yuvarlama olmaması
Bu işaret ile haneye yazılacak sayı varsa yazılır. Aşağıdaki örnekte küsurat hanesi 5 taneye kadar müsade edilmiş. Ancak elimizdeki para değeri sadece 3 haneye sahip. Dolayısıyla yazılacak sayılar yazılıyor, geri kalan haneler doldurulmuyor
BigDecimal money = BigDecimal ("123.234");
DecimalFormat df = new DecimalFormat("#.#####");
df.format(money);//123,234 verir
# işareti ile yuvarlama olması
Şöyle bir kod olsun.
DecimalFormat df = new DecimalFormat("#.##");
System.out.println(df.format(18.566666666666663));
Çıktı olarak şunu alırım.
18.57

 # işareti ile yuvarlama olması ve 0'ın atılması
BigDecimal money = new BigDecimal ("17.299999999999997");
DecimalFormat df = new DecimalFormat("###.##");
df.format (money); //17,3 verir

0 işareti
Bu işaret ile haneye yazılacak sayı varsa yazılır. Yoksa geri kalan haneler 0 ile doldurulur. Aşağıdaki örnekte bu durum gösterilmiş.
BigDecimal money = new BigDecimal ("123.234");
DecimalFormat df = new DecimalFormat("#.000000");
df.format (money); //123,234000 verir