09 Nisan 2009

Java listelerinizi, dizilerinizi sıramala

Merhaba,

Elinizde bir liste ve dizi var. Listedeki nesnelerin bir veya birden çok özelliğine göre listeyi sıralamak istiyorsunuz. Aşağıdaki utility sınıf tam bu iş için. Birden fazla özelliğe göre de sıralayabilirsiniz.

import java.lang.reflect.Method;

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

 

/**

 * @author M Morkoc

 * Bu sınıf ile nesne dizisi veya collection yapısında bulunan elemanlar sıralanır.

 */

public class Sorter {

      private final static Log log = LogFactory.getLog(Sorter.class);

      

      public static void sort(Object[] liste, String metodAdi) {

            sort(liste, new String[] {metodAdi}, true);

      }

 

      /**

       * liste dizisini sıralar.

       */

      @SuppressWarnings("unchecked")

      public static void sort(Object[] liste, String metodAdi, final boolean artan) {

            sort(liste, new String [] {metodAdi}, artan);

      }

 

     

      public static void sort(Object[] liste, String[] metodAdi) {

            sort(liste, metodAdi, true);

      }

 

      /**

       * liste dizisini coklu eleman icin siralar.

       */

      @SuppressWarnings("unchecked")

      public static void sort(Object[] liste, String[] metodAdi, final boolean artan) {

            if (liste.length == 0)

                  return;

            try {

                  final Method[] m = new Method[metodAdi.length];

                  for (int i = 0; i < m.length; i++) {

                        m[i] = liste[0].getClass().getMethod(metodAdi[i], new Class[0]);

                  }

                  Arrays.sort(liste, new ComparatorWithMethodNameList(m, artan));

            } catch (Exception e) {

                  log.error(e);

            }

      }

 

      @SuppressWarnings("unchecked")

      public static void sort(List liste, String metodAdi) {

            sort(liste, new String[] {metodAdi}, true);

      }

 

      /**

       * Gönderilen listeyi metodAdi isimli metodun her nesne için verdiği değerler ile sıralar

       * @author Ahmet Semiz

       */

      @SuppressWarnings("unchecked")

      public static void sort(List liste, String metodAdi, final boolean artan) {

            sort(liste, new String[] {metodAdi}, artan);

      }

 

      @SuppressWarnings("unchecked")

      public static void sort(List liste, String[] metodAdi) {

            sort(liste, metodAdi, true);

      }

 

      @SuppressWarnings("unchecked")

      public static void sort(List liste, String[] metodAdi, final boolean artan) {

            if (liste.size() == 0)

                  return;

            try {

                  final Method[] m = new Method[metodAdi.length];

                  for (int i = 0; i < m.length; i++) {

                        m[i] = liste.get(0).getClass().getMethod(metodAdi[i], new Class[0]);

                  }

                  Collections.sort(liste, new ComparatorWithMethodNameList(m, artan));

 

            } catch (Exception e) {

                  log.error(e);

            }

      }

}

Bu sınıf arta tarafta sıralama için aşağıdaki sınıfı kullanıyor. Anlaşılırlığı kolay olması için ayrı bir sınıfta sıralama yapıldı.

 

import java.lang.reflect.Method;

import java.text.Collator;

import java.text.RuleBasedCollator;

import java.util.Comparator;

 

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

 

import tr.com.innova.common.middleware.utils.LocaleHolder;

 

class ComparatorWithMethodNameList implements Comparator<Object> {

 

      private final static Log log = LogFactory.getLog(ComparatorWithMethodNameList.class);

     

      private final Method []m;

      private final boolean ascending;

      private final RuleBasedCollator ruleBasedCollator;

     

      ComparatorWithMethodNameList(Method []m, boolean ascending){

            this.m = m;

            this.ascending = ascending;

            ruleBasedCollator = (RuleBasedCollator) Collator.getInstance(LocaleHolder.getLocale());

      }

     

      public int compare(Object o1, Object o2) {

            try {

                  int sonuc = 0;

                  for (int i = 0; i < m.length; i++) {

                        Object obj1 = m[i].invoke(o1, new Class[] {});

                        Object obj2 = m[i].invoke(o2, new Class[] {});

                        sonuc = checkNullsAndCompare(obj1, obj2);

                        if (sonuc != 0) {

                              return sonuc;

                        }

                  }

            } catch (Exception e) {

                  log.error(e.getMessage());

            }

            return 0;

      }

 

      /**

       * @author Ahmet Semiz

       * displayTag projesinden aldım

       */

      @SuppressWarnings("unchecked")

      public final int checkNullsAndCompare(Object object1, Object object2) {

            int returnValue = 0;

           

            if (object1 instanceof String) {

                  returnValue = ruleBasedCollator.compare(object1.toString(), object2.toString());

            } else if (object1 instanceof Comparable && object2 instanceof Comparable) {

                  returnValue = ((Comparable) object1).compareTo(object2);

            } else if (object1 != null && object2 != null) {

                  // if object are not null and don't implement comparable, compare using string values

                  returnValue = ruleBasedCollator.compare(object1.toString(), object2.toString());

            } else if (object1 == null && object2 != null) {

                  returnValue = 1;

            } else if (object1 != null && object2 == null) {

                  returnValue = -1;

            } else {

                  // both null

                  returnValue = 0;

            }

 

            return (ascending ? 1 : -1) * returnValue;

      }

}

 

Kolay gelsin.


Rakamları Yazıya Çevirme

Merhaba,


Birçok yerde görürüz hep. Parasal değerlerin yazı ile belirtilmesi. Mesela dekont, gider pusulası vs. yerlerde. İnternette bu konuda yazılmış bir kod aradım ama Türkçe yapısına uygun ve anlaşılması kolay bulamadım.  https://www.informit.com/articles/article.aspx?p=342034&seqNum=3 adresindeki algoritma hem sadeliği hem de işleme biçimi ile ilgimi çekti. Gerçi bu makale kod hatalarını düzeltme pratiği için bu örneği vermiş ama herkes nasibinden faydalanır işte. Türkçe için düşününce bazı kısımları değiştirmek zorunda kaldım. Farklı yerlede de çalışır şekilde düzenledim.  

 

Çalışma mantığı şu şekilde özetle : Sayısı üçlük yapıda değerlendiriyor. Mesela 330.444' için önce 330'luk kısmı ele alıyor, sonra 444'lük kısmı. Her işlem sonucu sayısı kata bölüyor ve kalanı sayıya atıyor. Böylelikle 3'er geri gitmiş oluyor.

 

Umarım ihtiyacı olanlara faydalı olur. Ben şuan uğraştığım Gider Pusulası basımında kullanıyorum.

 

import java.math.BigDecimal;


public class TurkishNumber {

      private static final String[] birler = { " BİR", " İKİ", " ÜÇ", " DÖRT", " BEŞ", " ALTI", " YEDİ", " SEKİZ", " DOKUZ"};

      private static final String[] onlar = {" ON", " YİRMİ", " OTUZ", " KIRK", " ELLİ", " ALTMIŞ", " YETMİŞ", " SEKSEN", " DOKSAN" };

      private static final String[] katlar = { "", " BİN", " MİLYON", " MİLYAR", " TRİLYON"};

 

      public static void main(String[] args) {

            System.out.println("0 : " + TurkishNumber.sayi2YaziForParaFormatli(0));

            System.out.println("1 : " + TurkishNumber.sayi2YaziForParaFormatli(1));

            System.out.println("12 : " + TurkishNumber.sayi2YaziForParaFormatli(12));

            System.out.println("100 : " + TurkishNumber.sayi2YaziForParaFormatli(100));

            System.out.println("1234 : " + TurkishNumber.sayi2YaziForParaFormatli(1234));

            System.out.println("12345 : " + TurkishNumber.sayi2YaziForParaFormatli(12345));

            System.out.println("123456 : " + TurkishNumber.sayi2YaziForParaFormatli(123456));

            System.out.println("1234567 : " + TurkishNumber.sayi2YaziForParaFormatli(1234567));

            System.out.println("12345678 : " + TurkishNumber.sayi2YaziForParaFormatli(12345678));

            System.out.println("123456789.00 : " + TurkishNumber.sayi2YaziForParaFormatli(123456789));

            System.out.println("1234567890.9 : " + TurkishNumber.sayi2YaziForParaFormatli(1234567890.9));

            System.out.println("12345678.90 : " + TurkishNumber.sayi2YaziForParaFormatli(12345678.90));

            System.out.println("12345678.09 : " + TurkishNumber.sayi2YaziForParaFormatli(12345678.09));      

            System.out.println("123456789123.89 : " + TurkishNumber.sayi2YaziForParaFormatli(123456789123.89));

      }

 

      public static String sayi2Yazi(long sayi) {

            StringBuffer sonuc = new StringBuffer();

            // Go through the number one group at a time.

            for (int i = katlar.length - 1; i >= 0; i--) {

                  // Is the number as big as this group?

                  long cutoff = (long) Math.pow((double) 10, (double) (i * 3));

                  if (sayi >= cutoff) {

                        int thisPart = (int) (sayi / cutoff);

                        if (thisPart >= 100) {

                              if (thisPart / 100 > 1) {

                                    sonuc.append(birler[thisPart / 100 -1]);

                              }

                              sonuc.append(" YÜZ");

                              thisPart = thisPart % 100;

                        }

                        if (thisPart >= 10) {

                              sonuc.append(onlar[(thisPart / 10) - 1]);

                              thisPart = thisPart % 10;

                        }

                        if (thisPart >= 1) {

                              if (!(cutoff == 1000 && thisPart == 1)) {

                                    sonuc.append(birler[thisPart-1]);

                              }

                        }

                        sonuc.append(katlar[i]);

                        sayi = sayi % cutoff;

                  }

            }

 

            if (sonuc.length() != 0) {

                  sonuc.deleteCharAt(0);

            }

            return sonuc.toString();

      }

     

      public static String[] sayi2YaziForPara(double para) {

            String[] sonuc = new String[]{"", ""};

            if (para == 0) return sonuc;

            String strPara = new BigDecimal(para).setScale(2, 4).toString();

            int dotIndex = strPara.indexOf(".");

            long kusurat = Long.valueOf(String.valueOf(strPara).substring(dotIndex+1));

            sonuc[0] =  sayi2Yazi((long)para);

            if (kusurat > 0) {

                  sonuc[1] = sayi2Yazi(kusurat);

            }

            return sonuc;

      }

     

      public static String sayi2YaziForParaFormatli(double para) {

            StringBuffer sonuc = new StringBuffer();

            String[] sonucListesi = sayi2YaziForPara(para);

            if (!sonucListesi[0].isEmpty()) {

                  sonuc.append(sonucListesi[0]);

                  sonuc.append(" TL");

                  if (!sonucListesi[1].isEmpty()) {

                        sonuc.append(" ");

                        sonuc.append(sonucListesi[1]);

                        sonuc.append(" KURUŞ");                  

                  }

            }    

            return sonuc.toString();

      }

}

 

0 :

1 : BİR TL

12 : ON İKİ TL

100 : YÜZ TL

1234 : BİN İKİ YÜZ OTUZ DÖRT TL

12345 : ON İKİ BİN ÜÇ YÜZ KIRK BEŞ TL

123456 : YÜZ YİRMİ ÜÇ BİN DÖRT YÜZ ELLİ ALTI TL

1234567 : BİR MİLYON İKİ YÜZ OTUZ DÖRT BİN BEŞ YÜZ ALTMIŞ YEDİ TL

12345678 : ON İKİ MİLYON ÜÇ YÜZ KIRK BEŞ BİN ALTI YÜZ YETMİŞ SEKİZ TL

123456789.00 : YÜZ YİRMİ ÜÇ MİLYON DÖRT YÜZ ELLİ ALTI BİN YEDİ YÜZ SEKSEN DOKUZ TL

1234567890.9 : BİR MİLYAR İKİ YÜZ OTUZ DÖRT MİLYON BEŞ YÜZ ALTMIŞ YEDİ BİN SEKİZ YÜZ DOKSAN TL DOKSAN KURUŞ

12345678.90 : ON İKİ MİLYON ÜÇ YÜZ KIRK BEŞ BİN ALTI YÜZ YETMİŞ SEKİZ TL DOKSAN KURUŞ

12345678.09 : ON İKİ MİLYON ÜÇ YÜZ KIRK BEŞ BİN ALTI YÜZ YETMİŞ SEKİZ TL DOKUZ KURUŞ

123456789123.89 : YÜZ YİRMİ ÜÇ MİLYAR DÖRT YÜZ ELLİ ALTI MİLYON YEDİ YÜZ SEKSEN DOKUZ BİN YÜZ YİRMİ ÜÇ TL SEKSEN DOKUZ KURUŞ