日期中的代码优化:Java

时间:2015-07-25 01:33:43

标签: java

我有一个代码,用于打印子目录的创建日期。我得到了我的预期输出,但我编写代码的方式并不好,我认为它可以以更好的方式进行优化。正如您所看到的,循环内部有三行代码,每次循环运行都会执行,这会增加复杂性。

public static void main(String aa[]) throws IOException
{
        DateFormat simpleDateFormat = new SimpleDateFormat("MM-dd-yyyy");

        File file = new File("G:\\TestFiles");
        File[] files = file.listFiles();

        for(File subDir: files)
        {

        BasicFileAttributes attribute = Files.readAttributes(subDir.toPath(), BasicFileAttributes.class);

        FileTime filetime = attribute.creationTime();

        String strDate = simpleDateFormat.format(filetime.toMillis());

        System.out.println(strDate);

        }       

}

我试图以这样的方式编写我的代码:在for循环中我应该只有print语句,剩下的三行应该在我的for循环之外。我来的一种方法是声明我的子文件夹的路径但是它没有给出我的子文件夹的正确创建日期。

2 个答案:

答案 0 :(得分:3)

对我来说这很好......你可以把它剥离到:

    final DateFormat simpleDateFormat = new SimpleDateFormat("MM-dd-yyyy");
    final File file = new File("G:\\TestFiles");

    for (File subDir : file.listFiles()) {
      System.out.println(simpleDateFormat.format(Files.readAttributes(file.toPath(), BasicFileAttributes.class)
          .creationTime().toMillis())
      );
    }

...但请密切关注file.listFiles(),因为您可能很容易获得NPE(尽管您也没有在原始代码中检查它)。

答案 1 :(得分:2)

优化

您的问题并不清楚您的优化意味着什么。

外环线移动

for循环中执行的代码行需要在循环内运行。没有什么是未经优化的。我没有在代码中看到任何可以在循环外移动的内容。

如果您担心创建的对象几乎会立即被销毁并成为JVM垃圾收集器的“垃圾”......请不要担心。现代JVM经过精心打磨,并针对此类短期对象进行了优化。不要在长时间运行的循环(数十万或数百万次迭代)中轻率地创建这样的对象,但也不要担心它。

同样,请参阅下面的代码示例。请注意我如何在循环之前放置时区,语言环境和格式化程序。这些行在for循环中也可以正常工作,但是它们会反复执行并创建没有任何好处的新实例。这三个特定的对象是为了重用而构建的,所以我将它们移到了最顶层。在绘制代码时,我可能会将它们放在循环中,然后将它们标识为可以移出循环。

更少行

如果通过优化你的意思是为了缩短代码而减少行数,我强烈建议不要这样做有三个原因。

  • 代码的可读性比行数重要得多。程序员需要能够轻松阅读和理解代码,而不是破译它。
  • 如果你有简单的短代码,调试会容易得多。 “短”意味着专注于完成一个(或几个)特定操作(而不是实际的线长)。如果一行中发生了太多嵌套操作,那么在调试时跟踪值和效果会变得更加复杂。
  • 现代JVM技术,例如Oracle HotSpot& JRockit通过在编译期间和运行时期间优化代码来做出惊人的事情。在给出相对简单的直接代码行时,这些优化功能最强大。使代码过于密集或“聪明”可以实际减少 Java编译器/运行时优化的机会。

java.time

你可以做的一个重大改进是避免使用java.util.Date/.Calendar& SimpleTextFormat类。那些古老的课程在设计和实施方面都是出了名的麻烦。

这些类已在Java 8及更高版本的新java.time包中取代。这个新的日期时间框架受Joda-Time库的启发,由JSR 310定义,并由ThreeTen-Extra项目扩展。

您使用的FileTime类是java.time-savvy。请注意toInstant方法。

将所需/预期的时区(ZoneId)分配给该Instant。如果您未指定时区,则会隐式应用JVM的默认时区 - 通常更好的做法是指定而不是隐式依赖于默认值。请注意,JVM当前的默认时区可以随时由运行在该JVM中运行的任何应用程序的任何线程中的任何代码中更改。

Locale - 适当的方式创建字符串表示。

让我们想象一下Québécois经理正在研究与印度商业运营相关的数据。我们希望显示按照她的风俗格式化的日期时间值,但是在印度的时区中框架。时区对于确定日期至关重要(印度早些时候比加拿大早点出现)。

final ZoneId zoneKolkata = ZoneId.of( "Asia/Kolkata" );  // Adjust the date-time value as it would appear in India. Or, ZoneId.systemDefault()
final Locale localeQuébécois = Locale.CANADA_FRENCH;  // Or Locale.getDefault()
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( localeQuébécois ).withZone( zoneKolkata );

final File startingFile = new File( "/Users/brainydeveloper/Downloads" );  // "G:\\TestFiles"
for ( File file : startingFile.listFiles( ) ) {

    BasicFileAttributes attribute = null;
    try {
        attribute = Files.readAttributes( file.toPath( ), BasicFileAttributes.class );
    } catch ( IOException e ) {
        e.printStackTrace( );  // Add your own smart exception handling.
    }

    FileTime fileTime = attribute.creationTime( );
    String output = formatter.format( fileTime.toInstant( ) );
    System.out.println( output );
}

示例输出。

2014-04-19
2010-10-12
2015-06-21