Позиционный анализ строки в Java - PullRequest
1 голос
/ 15 февраля 2012

Я пытаюсь понять, как анализировать длинную строку и, основываясь на некотором индексе и длине, преобразовать это значение в определенный тип данных как можно быстрее, потому что мне нужно обрабатывать около 1000 строк / секунду. Чтобы было ясно, мне нужно что-то вроде этого

String initial = "4239898 mdj 8746bbbrts675420120214";

Someclass parser = new Someclass(initial);

Date date = parser.getDate(26,8);

Таким образом, дата анализируется с использованием подстроки из позиции 26–26 + 8

В общем, я хотел бы знать, существует ли уже класс, который помогает мне в этом, или кто-нибудь может предложить какой-нибудь быстрый алгоритм.

Заранее спасибо

Ответы [ 4 ]

2 голосов
/ 09 марта 2012

Я только что нашел действительно классную "основу" для своих целей.Он называется fixedformat4j, и он делает именно то, что я хочу, и с очень высокой производительностью, даже если он немного староват.

Вот базовый пример, найденный на его веб-сайте (http://fixedformat4j.ancientprogramming.com/):

@Record  
public class BasicRecord {  

  private String stringData;  
  private Integer integerData;  
  private Date dateData;  


  @Field(offset = 1, length = 10)  
  public String getStringData() {  
    return stringData;  
  }  

  public void setStringData(String stringData) {  
    this.stringData = stringData;  
  }  

  @Field(offset = 11, length = 5, align = Align.RIGHT, paddingChar = '0')  
  public Integer getIntegerData() {  
    return integerData;  
  }  

  public void setIntegerData(Integer integerData) {  
    this.integerData = integerData;  
  }  

  @Field(offset = 16, length = 10)  
  @FixedFormatPattern("yyyy-MM-dd")  
  public Date getDateData() {  
    return dateData;  
  }  

  public void setDateData(Date dateData) {  
    this.dateData = dateData;  
  }  
}  

Этот аннотированный класс теперь можно загружать и экспортировать с помощью FixedFormatManager

public class BasicUsage {  

  private static FixedFormatManager manager = new FixedFormatManagerImpl();  

  public static void main(String[] args) {  
    String string = "string    001232008-05-29";  
    BasicRecord record = manager.load(BasicRecord.class, string);  

    System.out.println("The parsed string: " + record.getStringData());  
    System.out.println("The parsed integer: " + record.getIntegerData());  
    System.out.println("The parsed date: " + record.getDateData());  

    record.setIntegerData(100);  
    System.out.println("Exported: " + manager.export(record));  
  }  
}  
1 голос
/ 15 февраля 2012
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Date;

public class SomeClass {
    public static void main(String []args)  {
        String initial = "4239898 mdj 8746bbbrts675420120214";

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Date parsed = new Date();

        try {
            parsed = format.parse(initial.substring(26,34));
        }
        catch(ParseException pe) {
            pe.printStackTrace();
        }

        System.out.println(parsed);
    }
}
0 голосов
/ 15 февраля 2012

Интересное объяснение от этой строки статьи

Класс StringBuilder был представлен в JDK 1.5. Это так же, как Класс StringBuffer, за исключением того, что StringBuilder не синхронизируется для многопоточные операции. Однако для однопоточной программы StringBuilder, без накладных расходов синхронизации, больше эффективный.

Полезное правило. Строки более эффективны, если они не изменены (потому что они являются общими в строке общего пула). Однако если вы приходится часто изменять содержимое строки (например, статус сообщение), вы должны использовать класс StringBuffer (или StringBuilder описано ниже) вместо.

Таким образом, вы можете поэкспериментировать с этими двумя классами или классом String по умолчанию. Решите, какой из них лучше всего работает в вашей ситуации. У меня есть следующий класс, который дает около 300 мс под чрезвычайно тяжелонагруженной системой.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class StringEfficientParser
{

    //String initial = "4239898 mdj 8746bbbrts675420120214";
    public static void parseString(String input) throws ParseException
    {

        StringBuilder sb = new StringBuilder(input);
        String input_date = sb.substring(26, 34);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyymmdd");
        Date date = sdf.parse(input_date);

    }

    public static void main(String[] args) throws ParseException
    {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++)
        {
            parseString("4239898 mdj 8746bbbrts675420120214");          
        }
        long stop  = System.currentTimeMillis();

        System.out.println("elapsed time : " + (stop - start));
    }

}
0 голосов
/ 15 февраля 2012

Нет ничего, о чем я знаю. Я не вижу, как это сделать быстрее, чем следующее:

public Date getDate(int start)
{
    int year = Integer.parseInt( initial.substring(start, start + 4) );
    int month = Integer.parseInt( initial.substring(start + 4, start + 6) );
    int day = Integer.parseInt( initial.substring(start + 6, start + 8) );
    return new Date(year, month, day);
}

Если все ваши даты в формате ГГГГММДД, это, вероятно, быстрее, чем использование класса SimpleDateFormat. (Обратите внимание, что вам не нужно передавать длину (8) в этом случае).

...