質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

Java 何かファイルを読み込んで、中の数字を用いて計算したいだけなのですが、どうすればいい? NumberUtils(API)って何?

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 3,595

Abeginner

score 29

Windows10でEclipseを用いてJavaの勉強をしています。
かなりの初心者ですが、よろしくお願いします。

目的としては、txtファイルやcsvファイルなどに保管されたデータを用いて、計算結果を出力したいのです。
ファイルの中身は、例えば
佐藤,数値A:12%,数値B:6.6,数値C:83,
鈴木,数値A:10%,数値B:7.8,数値C:55,
田中,数値A:9%,数値B:7.1,数値C:no data,
…みたいな感じを想定しています。

このデータで、数値A×数値C= をしたり、数値Bの合計を求めるとか、数値Cの平均値と分散を求める
とか、データ処理をしていけるようになりたいのです。
出力結果は、鈴木,X量:9.96とか、数値B平均:7.17とか、佐藤,数値C,検定Y:p<0.01 みたいなのをイメージしています。
要は、ふつうExcelでやるような計算です。
上記のデータ量だと、当然Excelの方が楽なのですが、最終的には100人とか1000人とか大量のデータを扱い、数値の種類も増え、複雑な統計処理なんかをできるようになりたいです。

上記の例では、データが無い時に数値の位置にno dataとか入ってきてしまいます。
実際、仕事になると、no dataが"-"だったり、"NC"とかだったり、ただの空欄""だったりする場合もあり得ます。
数字なのに"4.5*"(*は優位水準)とか"2.21E-8"だったりします。

こういった時に、うまく数字だけ取り出して、計算して、結果を出力させたいのです。
また、データ形式や統計処理などによって、大幅にプログラムを書き換えていては、間違いの元になりそうなので、ある程度シンプルで汎用性のある方法を知りたいのです。

そこで、漠然と「文字と数字を区別できるようにした方がいいかな」と思い、過去の質問1と、過去の質問2を見て、「NumberUtils(API)を使う方法がスッキリしていて良いかな」と思ったのですが、ダウンロードページNumberUtils(API)のページを見ても、どこを見て何をどう使えばいいのやらサッパリ…
きっと知っている人には何でもないページなんだと思うのですが、自分はそもそもNumberUtils(API)が何かもわかってないから、これを見ても情報が読み取れないんだと思うのです…

それに、NumberUtils(API)は、とりあえず試してみようと思っただけで、これが最適かどうかもわかっていません。
これって、4.5を数字と判断します? "4"と".(数字以外)"と"5"とか判断されちゃいます?
数字かどうか判断するだけで、変数に代入するのは、また別?
もしかしてNumberUtils(API)より簡単な方法ってありますか?
それ以前に、別の方法を使えば数字かどうか判断する必要性すらなかったりします?

ド素人過ぎて、何を疑問に思えばいいかもわからない状態ですが、最終的にファイル内の情報から数値("1"、"23%"、"4.5"、"6.7E-8"、"9**"のようなものを含む)を読み込んで計算できれば何でもいいです。
誰か助けて下さい。
この混乱状態を抜け出すきっかけとなれば、どんな情報でもいいです。
どうかよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

NumberUtils

NumberUtilsを使ってもよいですし、JREにあるクラスの機能のみを使ってもよさそうです。概観したところNumberUtilsで便利なのはint/double等の数値表現をどんなものでも統一的にNumber型として解析できる点にあるように見えます。後にも書きますがとりあえず数値はdoubleのみに統一したほうがいいと思えるのでNumberUtilsを使う必要性は低い気がします。もちろん使っても一向にかまわないとは思います。

これって、4.5を数字と判断します?

数値として認められるパターン(-1e-2などの指数形式なども含め)解析できます。

数字かどうか判断するだけで、変数に代入するのは、また別? 

NumberUtilsについてはそのとおりです。isXXXがtrueだったらcreateXXXを使い実際の値を得ます。JREのDouble.parseDouble, Integer.parseIntなどだと値をいきなり求めることになりますね。(変換できなければ例外)

数値("1"、"23%"、"4.5"、"6.7E-8"、"9**"のようなものを含む)を読み込んで計算

一般的な数値表現以外に%とか有意水準を扱うので、NumberUtilsを使うかどうかにかかわらずそのための解析が必要です。見る限り概ね次の戦略で解析できそうです。

A) 数値または特別な意味を持つ数値(%、有意水準、特殊な値)かどうかを最初に判断
B) 上記以外は文字列と想定

A)については
A1) "-", "", "NC", "NaN", "Infinity", etc.といった特殊な固定パターンを最初にチェック
A2) {数値}%, {数値}*のようなものは末尾が"%","*"かどうか判断しyesなら残りが実数かをチェック
A3) 上記以外は単に{数値}かどうかをチェック

最初に「数値を除く部分」をチェックし最後に残った部分が数値かをチェックするように考えると意外に簡単に解析ができます。

ある程度シンプルで汎用性のある方法を知りたいのです。

個人的意見としてはシンプルということなら最初は数値型にintやfloatやdoubleを混在させずにdoubleに統一するほうがよいと思います(WrapperクラスでいえばInteger, FloatはやめてDoubleのみにする)。他の言語、あるいはどこかに転がっているJavaの数値演算用のライブラリーにはこれらの色々な型の数値を統一的に演算できる機能を備えたものがあると思いますが、始めはあれこれライブラリーを探してインストールなどに苦労するより一通りjavaの標準ライブラリーを使い自分でクラスを定義しながら力を付ける方を優先することをお勧めします。

汎用的につくるというのはなかなか難しいテーマですが例えば「欠損値」を統一的に扱うためにdouble/Doubleではなく「doubleの値および欠損値の両方の状態を取れる」クラスを定義したほうがよいかも知れません。うまく定義してやると四則演算add,subtract,multiply,divide,sum,average,...,etc.といった演算メソッドを定義する際にどのように欠損値を扱うかを自分の目的に合った定義にできます。もしその定義が「統計処理を行う上で自然な定義」とできればそのクラスは自ずと汎用的で使いやすいものになるはずです。

どこを見て何をどう使えばいいのやらサッパリ… 

プログラミング経験が少ないうちはそんなものです。JREのDouble,Integer,Stringなどのクラスの関係ありそうなメソッドを一通り理解して使えるようになってくるとNumberUtilsのメソッドの意味も把握できるようになりますよ。最初は「1行読み込むのはどうすればいいの?カンマで区切るにはどうすれば?数値に変換する処理がややこしすぎる・・・」等々、なにかしようとするたびに躓くと思いますがそれはプログラミングを覚えるための必要なステップです。

最初はこのプログラムをいきなりつくるのは厳しいかも知れませんので、まずは簡単な処理から初めて少しずつ機能を広げてみるのをお勧めします。「ファイルから1行分をStringとして読み込み、カンマを区切りとして複数のStringへ分割し、それぞれを(ひとまず)数値として解析して加算して結果を出す」みたいな感じのプログラムから始めてみてはいかがでしょうか。機能を広げるうちに「あ、作り方間違えた」と感じるかも知れませんが、その失敗はあなたのプログラミング力を上げるのに必要なステップなので作り直しながら前へ進んでください。(どうするか迷ったら質問するのもよいです)

質問者さんはご自身を初心者とおっしゃってますが質問文をみた印象では実際に作ることでプログラミングの力を容易に伸ばしていけるポテンシャルをお持ちだと思いました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ArrayList<ArrayList<String[]>> a2
に最後の表示部分までに全ての情報を区切って入れるコードです
区切っただけでdouble型への変換などはしていません
使おうとすればdouble型かどうかを判別してクラス型に名前と変数の型を分けて一行ずつ入れなおすなどの工夫が必要だと思います

import java.util.*;
import java.io.*;

public class ALL {
 public static void main(String[] args) {

ArrayList<String[]> a=new ArrayList<>();
ArrayList<Dat> j=new ArrayList<>();

ArrayList<ArrayList<String[]>> a2=new ArrayList<>();

try(BufferedReader br=new BufferedReader(new FileReader("B.csv"))){

String data=null;


while((data=br.readLine())!=null){

a.add(data.split(","));

}

}catch(Exception r){}


for(int b=0;b<a.size();b++){
//s[]
ArrayList<String[]> p=new ArrayList<>();
Dat i=new Dat();
int co=0;
for(String n :a.get(b)){
//s
String[] c=n.split("[:|*|%|E]");
p.add(c);
}
a2.add(p);

}

for(ArrayList<String[]> l:a2){

for(String[] l2:l){

for(String l3:l2){
System.out.print(l3+" & ");
}
System.out.print(" & ");

}
System.out.println();

}



 }
 }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/10 18:37

    値と数値をStringとdoubleに入れるコードです E-8,E10などの10の何乗かを掛ける部分はできていませんがE以前の数値はdouble型に入ります 数値が壊れる事になるので掛け合わせなければいけませんが・・・
    import java.util.*;
    import java.io.*;

    public class ALL4 {
    public static void main(String[] args) {

    ArrayList<String[]> a=new ArrayList<>();
    ArrayList<Dat> j=new ArrayList<>();

    ArrayList<ArrayList<String[]>> a2=new ArrayList<>();

    try(BufferedReader br=new BufferedReader(new FileReader("B.csv"))){

    String data=null;


    while((data=br.readLine())!=null){

    a.add(data.split(","));

    }

    }catch(Exception r){}


    for(int b=0;b<a.size();b++){
    //s[]
    ArrayList<String[]> p=new ArrayList<>();
    Dat i=new Dat();
    int co=0;
    for(String n :a.get(b)){
    //s
    String[] c=n.split("[:|*|%|E]");
    p.add(c);
    }
    a2.add(p);

    }

    for(ArrayList<String[]> l:a2){

    for(String[] l2:l){

    for(String l3:l2){
    System.out.print(l3+"&");
    }
    System.out.print("$");

    }
    System.out.println();

    }

    ArrayList<Dat> v=new ArrayList<>();

    for(ArrayList<String[]> l:a2){
    int cou=0;
    Dat a22=new Dat();
    for(String[] l2:l){

    int count=l2.length-1;
    int flag=0;
    for(String l3:l2){
    if(cou==0 && count==0){
    a22.name=l3;

    }
    try{
    double w=Double.parseDouble(l2[count]);
    a22.d[cou-1]=w;

    }catch(Exception t){}
    count--;
    }

    cou++;


    }


    v.add(a22);
    }


    for(Dat y:v){

    System.out.print(y.name+" ");
    for(int i=0;i<y.d.length;i++){
    System.out.print(y.d[i]+" ");
    }
    System.out.println();

    }

    //この時点でArrayList<Dat> vに全ての情報が入っている

    }
    }


    class Dat{


    String name="";
    double d[]=new double[3];



    }

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Javaに関する質問
  • Java 何かファイルを読み込んで、中の数字を用いて計算したいだけなのですが、どうすればいい? NumberUtils(API)って何?