2

私は、ユーザーのテキスト入力に基づいてデータの分析を実行する Web アプリケーションである小さなプロジェクトを開発しています。

そのためには、単語とその単語に対応するスコアを含む Map を使用する必要があります。

これは私が試したものです:

public class EnDict {
    private static Map<String, Integer> map = new HashMap<String, Integer>() {
        {
            put("abandon", -2);
            put("ability", 2);
            put("abuse", -3);
            //and so on, thousands of pairs
        }
    }
}

それは機能しますが、この方法では、キーと値のペアをクラスにハードコーディングする必要があります。したがって、さらにペアを追加したい場合は、ペアを追加するだけでテキスト ファイルを作成するのではなく、コードを記述する必要があります。良くないようです。

したがって、このペアをテキスト ファイルから取得したいと考えています。また、アプリケーションの起動時にこのマップを作成する必要があるため、ユーザーが要求を行うと、マップは既に読み込まれており、分析ロジックで使用できます。つまり、Map は最初のリクエストが発生する前にメモリ内に存在し、その後、後続のリクエストで使用するために最後にメモリ内に存在する必要があります。そして、アプリケーションのどこからでも見えるようにする必要があります (この部分はあまり明確ではなかったかもしれませんが、もっとうまく説明する方法がわかりません)。

私はいくつかの調査を試みましたが、アプリケーションの開始以来、マップをメモリに保持するというこの特定の部分に対する答えは見つかりませんでした。クラスApplication_Startの ASP.NET メソッドに似たものです。Global

私はプログラミング、特にJavaに非常に慣れていないため、このタスクを達成するための最良の方法について完全に誤解されている可能性があります。その場合は、ヒントをいただければ幸いです。

サーブレット、JSP、および Tomcat を使用しています。

編集: 実際には、1 つのマップだけではありません。いくつかのマップがあり、それらのマップは同一のキーを持つことができます。

4

6 に答える 6

4

このマップを静的として定義します。このマップは、このクラスをロードしたクラス ローダーがガベージ コレクトされなくなるまでメモリ内に存在します。

上記を参照して言います:http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#12.7

静的メンバーはクラスにリンクされており、上記の仕様では、クラスローダーが配置されるまでクラスはアンロードされません。

オブジェクトはガベージコレクションを取得しますが。したがって、マップを静的にすることをお勧めします(外部からのアクセスが必要な場合に備えて、マップも公開してください)。

ファイルをマップにロードするため

としてファイルに保存します

キー1=値1 キー2=値2 .... ....

以下のように BufferedReader を使用するようになりました

BufferedReader reader = new BufferedReader(new FileReader(new File("pathname")));
        String line = null;
        Map<String, Integer> map = new HashMap<String, Integer>();// it should be static - whereever you define
        while ((line = reader.readLine()) != null) {
            if (line.contains("=")) {
                String[] strings = line.split("=");
                map.put(strings[0], Integer.parseInt(strings[1]));
            }
        }

クラスローダーは、アプリケーションの起動時にクラスをメモリにロードするものです。Tomcat には、必要なクラス (オブジェクトではなくクラス) をメモリにロードするクラスローダーもあります。これで、静的変数はオブジェクトではなくクラスに関連付けられていることがわかりました。したがって、静的メンバーはクラスとともにメモリにロードされます。他の多くの場合、クラスのオブジェクトを作成して使用します。何百万ものオブジェクトがメモリにロードされている場合、すぐに足りなくなります。したがって、Javaにはガベージコレクターと呼ばれるものがあります。このガベージ コレクタは、不要なオブジェクトや古いオブジェクトをメモリから削除してリサイクルします。ガベージ コレクターはクラスではなくオブジェクトを削除するため、静的メンバーは引き続きメモリに残ります。

于 2013-09-06T14:35:07.980 に答える
3

次のように、静的ブロックで静的変数を静的に初期化できます。

private static Map<String, Integer> map = new HashMap<String,Integer>();

static {
    fillMap(map, "filename.txt");
}

private static void fillMap(Map<String, Integer> map, String fileName) {
   // here comes file reading code with loop
}

ファイルの読み方は、 Java でプレーン テキスト ファイルを読む のようなものを参照してください。

アプリケーションの起動時にすべての静的マップが初期化される限り。

于 2013-09-06T14:23:59.460 に答える
1

テキスト ファイルをアプリケーションにロードするには、これを試してください:テキスト ファイルからハッシュ マップまたはリストに読み込む

プログラミングを始めたばかりの頃、私は多くのグローバル変数を使いたくなったことを知っています。結局のところ、これは通常、最善の戦略ではありません ( http://c2.com/cgi/wiki?GlobalVariablesAreBadを参照)。

おそらく、メイン メソッドで最初に辞書をロードし、後で必要になる他のメソッドに渡すことができます。

于 2013-09-06T14:31:10.917 に答える
1

web.xml ファイルでリスナーを定義できます。

<listener>
    <listener-class>my.Listener</listener-class>
</listener>

そして、クラスを実装します:

package my;

public class Listener implements javax.servlet.ServletContextListener {

   public void contextInitialized(ServletContext context) {
       File file = new File();
       fileEntries = ... // load your entries
       for (Object[] line : fileEntries) {
           YourClass.get().addElement((String) line[0], Integer.parseInt(line[1].toString());
       }
   }
}

Map アプリケーション全体にアクセスする場合は、シングルトンを作成するか、Spring を使用してクラスを管理します。シングルトンが次のようなことを行う場合:

public class YourClass {
     private static final YourClass INSTANCE = new YourClass();

     private Map<String, Integer> yourMap;

     private YourClass() {
         yourMap = new HashMap<>();
     }

     public static final YourClass get() {
         return INSTANCE;
     }

     public void addElement(String key, Integer value) {
         yourMap.put(key, value);
     }

     public Integer getValueForKey(String key) {
         return yourMap.get(key);
     }
}

したがって、次の方法でアプリケーションのどこからでも要素にアクセスできます。

YourClass.get().getValueForKey("yourKey");
于 2013-09-06T14:35:07.960 に答える
0

さまざまなリソースからさまざまな Java クラスに定数をロードするには、Apache Commons 構成ライブラリhttp://commons.apache.org/proper/commons-configuration/を使用できます。

アプリケーションの起動には、使用できます

<servlet>
    <servlet-name>StartUp</servlet-name>
    <display-name>StartUp Servlet</display-name>
    <servlet-class>foo.bar.YourStartUpServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet> 
于 2013-09-06T14:32:14.357 に答える