2

ファイル名と、指定された日に最後に変更された時刻のログを表示しています。その内容は次のようになります。

(comment:file_02389.txt,lastmodified:Wed Oct 10 19:10:49)
(comment:file_02342.txt,lastmodified:Wed Oct 10 17:16:08)
(comment:file_02315.txt,lastmodified:Wed Oct 10 18:45:12)
(comment:file_02344.txt,lastmodified:Wed Oct 10 08:31:01)

ログは、改行のない単一の文字列として提供されます。文字列を解析して、最近変更されたファイル、つまり最新の日付を持つファイル(この場合はfile_02389.txt)を見つけたいと思います。各「コメント」の文字の長さは一定ですが、仮想的には将来変更される可能性があり、同じファイルが複数回変更された場合、ファイル名は一意になりません。

最新のファイルを見つけるための最も拡張可能/保守可能な方法はありますか?実行時間とメモリは重要な要素ではありません。主な懸念事項は、初心者プログラマーがコードを理解して操作できることです。

私の最初の考えは、文字列をカスタムコンパレータでソートできるリストに分割することでした。これは単純ですが、拡張可能ではないと思います。

{//given String log
...
//setup
List<String> temp = Arrays.asList(log.trim().split("\\(comment\\:")); //too complex for one line?
//the first entry is blank so it must be removed else a substring() call will fail
if(temp.get(0).equals(""))
    temp.remove(0);
int period = full.get(0).indexOf('.');
int colon = full.get(0).indexOf(':');

//process
Collections.sort(temp, DATE);
return test.get(test.size()-1).substring(0, period)) //last entry is the most recent
}

public final Comparator<String> DATE = new Comparator<String>()
{
public int compare(String s1, String s2)
    {
        return s1.substring(28).compareTo(s2.substring(28));
    } 
};

これは機能しますが、行の長さに依存するサブストリングと、この単一の場合にのみ役立つコンパレータを使用します。.splitを使用してから最初のエントリを削除する必要はありませんが、それが代替手段である場合は、真の理解しにくい正規表現を避けたいと思います。整数または日付オブジェクトとして比較するのではなく、日付を文字列として扱うことは望ましくないように思われますが、コード行を節約できます。

私は現在、ランダムに見える番号で使い捨てのコンパレータを作成することを回避するソートされたマップを使用していますが、特殊なマップは、私がやろうとしていることに対してかなり複雑に見えます。ファイル名用に1つの配列を作成し、時刻用に別の配列を作成してから、時刻をコピーするために3番目の配列を作成して、時刻配列を並べ替え、その最後の値をコピー内の対応するインデックスと比較できるようにするよりも、まだ良いと思います。

{
...
//same setup as before
//process
//key is time, value is file name
SortedMap<String, String> map = new TreeMap<String, String>();
for(String s : temp)
    map.put(s.substring(colon+1), s.substring(0, period));
//the value to which the last key is mapped is guaranteed to be the most recent file
return map.get(map.lastKey()); //too complex for one line?
}
4

2 に答える 2

2

他の人が提案することに興味がありますが、私の最初の本能は、元の文字列をjson配列に変換することです(いくつかの置換クエリを使用)。次に、その json を逆シリアル化し、それぞれがコメントと日付の 2 つのプロパティを持つオブジェクト インスタンスのリストをすぐに取得できます。

これらのオブジェクトのコンパレータを使用して、リストを希望どおりに並べ替えることができます。

于 2012-10-11T21:08:05.523 に答える
2

このようなものは機能しますか?基本的に、各行から日付を解析し、「ペア」オブジェクトのコレクションを構築して、日付に基づいてコレクションを並べ替えることができます。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;


public class Parse {

    /**
     * @param args
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {
        StringBuilder sb = new StringBuilder();
        sb.append("(comment:file_02389.txt,lastmodified:Wed Oct 10 19:10:49)").append("\n");
        sb.append("(comment:file_02342.txt,lastmodified:Wed Oct 10 17:16:08)").append("\n");
        sb.append("(comment:file_02315.txt,lastmodified:Wed Oct 10 18:45:12)").append("\n");
        sb.append("(comment:file_02344.txt,lastmodified:Wed Oct 10 08:31:01)").append("\n");

            //create a date format that can parse dates formatted in the file
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss");

            //read the file into an array of lines (or read one line at a time)
        String[] lines = sb.toString().split("\n");

            //create an array of pair objects to hold the line as well as the date
        List<Pair> list = new ArrayList<Pair>();


        for(int i=0;i<lines.length;i++){
                    //get the date component of the line
            String dateString = lines[i].substring(lines[i].length()-20, lines[i].length()-1);

            Pair pair = new Pair();
            pair.date = sdf.parse(dateString); 
            pair.line = lines[i];
            list.add(pair);
        }
        Collections.sort(list);
        System.out.println(list.get(list.size()-1).line);
    }
}
class Pair implements Comparable<Pair>{

    public Date date;
    public String line;

    @Override
    public int compareTo(Pair o) {
        return date.compareTo(o.date);
    }

}
于 2012-10-11T21:55:09.293 に答える