2011-11-10 7 views
1

私が仕事をしているほとんどのプロジェクトには、読んでからルックアップを返す必要のあるタブ区切りファイルがあります。それ。私は自分自身が同じ方法を何度も何度も書き直すことに気づきます。より一般的なものを作成したいので、いつもコピー&ペーストのコードを行う必要はありません。下のコードから、私は9行目と16-19だけを変更します。だから私はMap<key, value>と、どのように私はマップにデータを入力したいの実装を変更します。この方法から汎用的なプロセスを作成する方法はありますか?このメソッドを呼び出すたびに、Mapにデータを入力する方法を実装し、Mapをより一般的な型に変更しますよくタブ区切りファイルを読み込んで一般的なマップを返すジェネリックプロセスを作成する方法

1. public Map<String, PackageLog> readAllLogsIntoMap(File file){ 
2.  if (!file.exists()) 
3.  { 
4.   return new HashMap <String, PackageLog>(); 
5.  } 
6.  BufferedReader reader = null; 
7.  FileReader fileReader = null; 
8.  String data = null; 
9.  Map <String, PackageLog> resultMap = new HashMap <String, PackageLog>(); 
10.  try 
11.  { 
12.   fileReader = new FileReader(file); 
13.   reader = new BufferedReader(fileReader); 
14.   while ((data = reader.readLine()) != null) 
15.   { 
16.    PackageLog pl = new PackageLog(data); 
17.    if(!pl.getPdfName().equals("")){ 
18.     resultMap.put(pl.getPdfName(), pl); 
19.    } 
20.   } 
21.  } catch(Exception e){ 
22.   
23.  } 
24.  finally 
25.  { 
26.   try{ 
27.    if (reader != null) reader.close(); 
28.    if (fileReader != null) fileReader.close(); 
29.   }catch(IOException ioe){ 
30.    
31.   } 
32.  } 
33.  return resultMap; 
34. } 

答えて

3
  1. 抽象Utilのクラスでこのメソッドを置きます。ジェネリック薬を使用する。
  2. 9行目と16-19行目で実行するロジックを抽象メソッドに委譲します。
  3. 例えば、このクラスの用途

でこれらの抽象メソッドを定義します。

public abstract class ReaderUtil<K, V> { 

protected abstract Map<K, V> newMap(); 
protected abstract void doThings(String data, Map<K, V> resultMap); 

public Map<K, V> readAllLogsIntoMap(File file){ 
     if (!file.exists()){ 
      return newMap(); 
     } 
     BufferedReader reader = null; 
     FileReader fileReader = null; 
     String data = null; 
     Map <K, V> resultMap = newMap(); 
     try { 
     fileReader = new FileReader(file); 
     reader = new BufferedReader(fileReader); 
     while ((data = reader.readLine()) != null){ 
      doThings(data, resultMap); 
     } 
    } catch(Exception e){ 

    } 
    finally{ 
     try{ 
      if (reader != null) reader.close(); 
      if (fileReader != null) fileReader.close(); 
     } catch(IOException ioe){ 

     } 
    } 
    return resultMap; 
} 
} 

そして使用の可能性:

ReaderUtil<String, PackageLog> reader = new ReaderUtil<String, PackageLog>(){ 
    protected Map<String, PackageLog> newMap() { 
     return new HashMap<String, PackageLog>(); 
    } 
    protected void doThings(String data, Map<String, PackageLog> resultmap){ 
     PackageLog pl = new PackageLog(data); 
     if(!pl.getPdfName().equals("")){ 
      resultMap.put(pl.getPdfName(), pl); 
     } 
    } 
}; 
Map<String, PackageLog> myMap = reader.readAllLogsIntoMap(); 

を考慮してください、あなただけnewMap()方法を必要とします異なるマップ実装を提供したい場合あなたはgenerizedクラスの中でよくnew HashMap<K, V>()をすることができます。

また、例外を処理するためのフックメソッド(オーバーライド可能な多分空のメソッド)を定義することもできます。

+0

これはすばらしく見えます。私はちょうどあなたのために1つの質問があります。メソッドnewMap()が本当に必要ですか?ですから 'if(!file.exists())'をチェックすると、新しいHashMap ();を返すことができますか?これに何か問題はありますか? –

+0

オハイオ州私は、あなたは私の上記の質問に答えた参照してください。しかし、私はあなたがこのマップの意味を理解していません。異なるマップ実装を提供したい場合は、newMap()メソッドが必要です。あなたは精緻化できますか? –

+0

実際、答えで述べたように、実装が 'Map'(' HashMap'、 'TreeMap'など)のさまざまな実装を提供したい場合にのみ必要です。この場合でも、保護された抽象クラスgetMapClass()、またはジェネリックに縮小し、リフレクションを通じてインスタンス化を実行できます。 –

1

ハリー、Javaは、例えばDプログラミング言語のようなタイピープ型をサポートしていないと考えて、public Map<String, Object[]> csvToMap(File argFile, char argSeparator, Class[]) {}のような署名を持つメソッドをリファクタリングする必要があります。次に、それをmymap = csvToMap("/tmp/some.log", ';', { Date.class, String.class, Double.class});のように呼び出します。この呼び出しは、次のような行を含むCSVファイルを解析するために使用される可能性があります。2011-11-23;Some Name;232.22

+0

実際、私は自分のlibのためにこの関数をコーディングします。私が必要とするのは、CSVファイルを解析し、いくつかのコレクションオブジェクトにデータを取り込むことだけです。 :) – DejanLekic

3

public interface LookupKey<K, T> { 
    K keyFor(T t); 
} 

public <K, T> Map<K, T> readAllLogsIntoMap(File file, Class<T> tClass, LookupKey<K, T> lookupKey) { 
    BufferedReader reader = null; 
    Map<K, T> resultMap = new LinkedHashMap<K, T>(); 
    if (!file.exists()) 
     return resultMap; 
    try { 
     Constructor<T> tConstructor = tClass.getConstructor(String.class); 
     reader = new BufferedReader(new FileReader(file)); 
     String data; 
     while ((data = reader.readLine()) != null) { 
      T t = tConstructor.newInstance(data); 
      K key = lookupKey.keyFor(t); 
      if (key != null) 
       resultMap.put(key, t); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 

    } finally { 
     try { 
      if (reader != null) reader.close(); 
     } catch (IOException ignored) { 
     } 
    } 
    return resultMap; 
} 
+1

ニース、ピーター!:) – DejanLekic

+0

@Peter:List <>も返すことができるという点まで一般化することも可能ですか?今すぐマップを返すだけです。私はこれを別の質問にすることができます。 –

関連する問題