在子字符串中对子字符串进行排序

时间:2012-10-11 21:01:11

标签: java string comparator sortedmap

我正在查看文件名的日志以及他们在指定日期上次修改的时间。其内容如下:

(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。每个“注释”的字符长度是不变的,但假设将来可能会改变,如果同一文件被多次修改,文件名将不是唯一的。

是否有最可扩展/可维护的方法来查找最新文件?执行时间和记忆不是重要因素。主要关注的是初学者程序员可以理解并使用代码。

我的第一个想法是将String拆分为可以使用自定义Comparator排序的List。我认为这很简单但不可扩展:

{//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));
    } 
};

它可以工作但是使用依赖于行长度的子串和只在这种情况下有用的Comparator。我不喜欢使用.split然后必须删除第一个条目,但我想避免一个真实的,难以理解的正则表达式,如果这是一个替代。将日期作为字符串处理而不是作为整数或日期对象进行比较似乎是不可取的,但保存了代码行。

我目前使用的排序地图避免了创建一个具有随机数字的一次性比较器,但是我想要做的事情似乎是一个专门的地图相当复杂。我仍然认为这比为文件名创建一个数组更好,为时间创建另一个数组,然后是第三个复制时间,以便可以对时间数组进行排序,并将其最后一个值与副本中的相应索引进行比较。

{
...
//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?
}

2 个答案:

答案 0 :(得分:2)

我对其他人的建议感兴趣,但我的第一直觉是将你的原始字符串转换为json数组(带有一些替换查询)。然后,您可以反序列化该json并立即获取一个对象实例列表,每个对象实例都有两个属性,注释和日期。

您可以使用这些对象的比较器按照您希望的方式对列表进行排序。

答案 1 :(得分:2)

这样的事情会起作用吗? 基本上解析每行的日期,构建一个“Pair”对象的集合,然后我可以根据日期对集合进行排序。

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);
    }

}