ラベル Java の投稿を表示しています。 すべての投稿を表示
ラベル Java の投稿を表示しています。 すべての投稿を表示

2010/12/17

[Java]リフレクションしてみた

極簡単なリフレクションの例。
コピペ支援的な感じで。
import java.lang.reflect.Constructor;

public class ReflectionTest {
   public static void main(String[] args) {
      try {
         // create String instance
         String string_classStr = "java.lang.String";
         Class<String> string_class = (Class<String>) Class.forName(string_classStr);
         Class string_argTypes[] = { String.class };
         Constructor<String> string_constructor = string_class.getConstructor(string_argTypes);
         Object string_constructorArgs[] = { "TESTING@TESTONG" };
         String string = (String) string_constructor.newInstance(string_constructorArgs);
         System.out.println(string);
         
         // call toString() method
         Method string_toString = string_class.getMethod("toString", null);
         String dst_string = (String) string_toString.invoke(string, null);
         System.out.println(dst_string);
         
         // call split("@") method
         Class string_split_argTypes[] = { String.class };
         Object string_split_args[] = {"@"};
         Method string_split = string_class.getMethod("split", string_split_argTypes);
         String[] string_splitArray = (String[]) string_split.invoke(string, string_split_args);
         for (String str : string_splitArray) {
            System.out.println(str);
         }
         
         // call String.format("num1 : %d, num2 : %d", 13, 14) methods (static method, and "13, 14" is var args)
         Class string_format_argTypes[] = { String.class, Object[].class };
         Object string_format_args[] = { "num1 : %d, num2 : %d", new Object[]{13, 14} };
         Method string_format = string_class.getMethod("format", string_format_argTypes);
         dst_string = (String) string_format.invoke(null, string_format_args);
         System.out.println(dst_string);
         
      } catch (NoSuchMethodException e) {
         e.printStackTrace();
      } catch (IllegalArgumentException e) {
         e.printStackTrace();
      } catch (InstantiationException e) {
         e.printStackTrace();
      } catch (IllegalAccessException e) {
         e.printStackTrace();
      } catch (InvocationTargetException e) {
         e.printStackTrace();
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }
   }
}
追記 reflection の綴りをがっつり間違えていたので修正しました。

2010/12/08

[Java][C]JNIのヘッダを作るメイクファイル

JNI のヘッダを作ってくれる Makefile

OUTPUT_DIR=jni/
CLASSPATH=bin/
PACKAGE_BASE=jp.dip.oyasirazu.jnitest.
DIRECTORY_BASE=jp/dip/oyasirazu/jnitest/
HEADER_BASE=${OUTPUT_DIR}jp_dip_oyasirazu_jnitest_

all: ${HEADER_BASE}JNITest.h \
     ${HEADER_BASE}TestClass.h

${HEADER_BASE}%.h : ${CLASSPATH}${DIRECTORY_BASE}%.class
   javah -classpath ${CLASSPATH} -d ${OUTPUT_DIR} ${PACKAGE_BASE}$(subst ${HEADER_BASE},,$*)
ちょうきもちわるい。
ヘッダは '_' 区切りだし、パッケージは '.' 区切りだし、ディレクトリは '/' 区切りだし...。
何か良い方法無いのかね?
make doc でシグネチャ一覧 txt をどこかに出力とかも便利かもねー。
きちんと調べれば ndk-build とか .mk とか編集するとできる気もする。
いつかきっと調べる。
でもこの辺がころころ変わることなんて滅多にないはずだから無駄な努力だった気もする。

2010/01/08

[Java]整数の各桁を足し合わせる問題

■ 整数の各桁を足し合わせる問題

5分で終わると聞いてやってみました。
5分問題 やってみた。 - 地獄の猫日記

■ ということで、作ってみた

負数が入力だった場合どうすれば良いのか解らなかったので、とりあえずマイナスは無視して数字を全部足す事にした。
・無難(?)な回答
public class PlaceNumberAdder02 {
   long number;
   public PlaceNumberAdder02(long number){
      setNumber(number);
   }

   public long addNumbers(){
      long number = this.number;
      long sum = 0;
      
      number = Math.abs(number);
      
      do {
         sum += number % 10;
      } while((number /= 10) != 0);
      
      return sum;
   }
   
   public void setNumber(long number){
      this.number = number;
   }
   
   public long getNumber(){
      return number;
   }
}
・変態(?)回答
public class PlaceNumberAdder01 {
   long number;
   public PlaceNumberAdder01(long number){
      setNumber(number);
   }
   
   public long addNumbers(){
      String numberStr = String.valueOf(number);
      long sum = 0;

      if(number < 0){
         numberStr = numberStr.substring(1);
      }
      
      for(int i = 0; i < numberStr.length(); i++){
         sum += Integer.parseInt(numberStr.substring(i, i+1));
      }
      
      return sum;
   }
   
   public void setNumber(long number){
      this.number = number;
   }
   
   public long getNumber(){
      return number;
   }
}
変態回答が01なのが問題だよねー。
・...言い訳をさせてもらうと
「3の倍数 or 3を含む」数の時にアホと表示するプログラムを書いた時に、数字を文字に変換して処理を行ったもんで、今回もそののりで書いてみた感じ。
普通に処理した場合(PlaceNumberAdder02)に比べて2から2.5倍くらい遅くなります。
しかし、プログラムの形的にも面白みの無い物になってしまったなぁ...。
あと、名前とかもっと考えようよ、自分。

■ テスト

・テストコード(とは言えない何か)
public class PlaceNumberAdderTest {
   static final long l1 = 1234, l2 = 9999, l3 = -65535;
   
   public static void main(String[] args) {

      System.out.println("Number = " + l1);

      PlaceNumberAdder01 pna1 = new PlaceNumberAdder01(l1);
      System.out.println("pna1: " + pna1.addNumbers());
      
      PlaceNumberAdder02 pna2 = new PlaceNumberAdder02(l1);
      System.out.println("pna2: " + pna2.addNumbers());

      System.out.println();
      System.out.println("Number = " + l2);

      pna1.setNumber(l2);
      System.out.println("pna1: " + pna1.addNumbers());
      
      pna2.setNumber(l2);
      System.out.println("pna2: " + pna2.addNumbers());

      System.out.println();
      System.out.println("Number = " + l3);

      pna1.setNumber(l3);
      System.out.println("pna1: " + pna1.addNumbers());
      
      pna2.setNumber(l3);
      System.out.println("pna2: " + pna2.addNumbers());

   }
}
・実行結果
Number = 1234
pna1: 10
pna2: 10

Number = 9999
pna1: 36
pna2: 36

Number = -65535
pna1: 24
pna2: 24
こんな感じ。

2009/12/17

[Java]カード配り問題に挑戦

■ カード配り問題に挑戦

qune: プログラミングメモ - カード配り問題とか
10分で終わると聞いてやってみました。
結局20分かかりました...。

■ ソースコード

public class Cards {
 public String[] deal(int numPlayers, String deck){
  String[] playerCards = new String[numPlayers];
  int cardNum = deck.length();
  
  //配列初期化
  for(int i = 0; i < numPlayers; i++){
   playerCards[i] = "";
  }
  
  //プレイヤーに同じ数のカードを配るために、余るカードは抜けておく
  int amari = cardNum % numPlayers; 
  deck = deck.substring(0, cardNum - amari);
  cardNum = deck.length();
  
  //一人に一枚づつすら配れない場合は誰にもカードを配らない
  if(cardNum == 0){ return playerCards; }
  
  //カードを配る
  for(int i = 0; i < cardNum; i++){
   playerCards[i%numPlayers] += deck.charAt(i);
  }
  
  //結果を返す
  return playerCards;
 }
}

public class CardsTest {
 public static void main(String[] args) {
  int numPlayers;
  String deck;
  String[] results;
  
  Cards cards = new Cards();

  //例1
  numPlayers = 6;
  deck = "012345012345012345";
  //Returns: {"000", "111", "222", "333", "444", "555" }
  results = cards.deal(numPlayers, deck);
  
  for(String result : results){
   System.out.print("\""+result+"\" ");
  }
  System.out.println();

  //例2
  numPlayers = 4;
  deck = "111122223333";
  //Returns: {"123", "123", "123", "123" }

  results = cards.deal(numPlayers, deck);
  
  for(String result : results){
   System.out.print("\""+result+"\" ");
  }
  System.out.println();

  //例3  
  numPlayers = 1;
  deck = "012345012345012345";
  //Returns: {"012345012345012345" }

  results = cards.deal(numPlayers, deck);
  
  for(String result : results){
   System.out.print("\""+result+"\" ");
  }
  System.out.println();
  
  //例4
  numPlayers = 6;
  deck = "01234";
  //Returns: {"", "", "", "", "", "" }

  results = cards.deal(numPlayers, deck);
  
  for(String result : results){
   System.out.print("\""+result+"\" ");
  }
  System.out.println();
  
  //例5
  numPlayers = 2;
  deck = "";
  //Returns: {"", "" }

  results = cards.deal(numPlayers, deck);
  
  for(String result : results){
   System.out.print("\""+result+"\" ");
  }
  System.out.println();
 }
}

■ 出力結果

"000" "111" "222" "333" "444" "555" 
"123" "123" "123" "123" 
"012345012345012345" 
"" "" "" "" "" "" 
"" "" 
ソースが無駄に長かった...。
そして別にsubstringする必要が無かった...orz
//プレイヤーに同じ数のカードを配るために、余るカードは抜けておく
int amari = cardNum % numPlayers; 
deck = deck.substring(0, cardNum - amari);
cardNum = deck.length();
上記は無駄。以下でokであることを確認...orz
cardNum -= cardNum % numPlayers;
いちいち文字列を作り直さないで、for文の繰り替えし数で調整すればいいじゃない。という話。うへぇ。

2008/01/30

[Memo]Mapクラスの正しい使用法

Mapクラスの正しい使用法 - ITアーキテクト [IT Architect]
  • すべてのキーと値を取得する場合はentrySetを使う。
  • LinkedHashMap—登録順序を保持するMap(初めて登録された順番、上書きは登録に入らない)
  • IdentityHashMap—IDでキーを判定するMap(キー同士の同一判定を==で行う)
  • WeakHashMap—弱参照で値を保持するMap