在Java中找到最年轻和最老的狗

时间:2014-09-17 21:21:02

标签: java date calendar tostring

我使用toString方法将我为月,日和年制作的整数放在一起。然后把它带到主程序。

public class Dog
{
    private String dogName;
    private int dogMonth;
    private int dogDay;
    private int dogYear;


public Dog(String name, int month, int day, int year)
{
    dogName  = name; 
    dogMonth = month;
    dogDay = day;
    dogYear = year;
} 
public String getName()
{
    return dogName;
}

public String toString()
{
    return String.format("%d/%d/%d", dogMonth, dogDay, dogYear);
}

然后我试着找出哪个是最低的。但我不知道我是否需要日历API。

  while(sc.hasNextLine())
  {

    // read a line from the input file via sc into line
        line = sc.nextLine();       

     StringTokenizer stk = new StringTokenizer(line);
     String name = stk.nextToken();
     int month = Integer.parseInt(stk.nextToken());
     int day = Integer.parseInt(stk.nextToken());
     int year = Integer.parseInt(stk.nextToken());


     Dog list = new Dog(name, month, day, year);

     dogs.add(list);
   }
   sc.close();


   String lowDate= dogs.get(0).toString();
   String lowName = dogs.get(0).getName();

   for (int i = 0; i< dogs.size(); i++)
   {
     String newLow= dogs.get(i).toString();
     String newName = dogs.get(i).getName();
     if(lowDate>newLow)
     {
       lowDate = newLow;
       lowName= newName;
     }
  System.out.println("The youngest dog is"+lowName+lowDate);

我如何找出最年轻和最老的?

例如:

文件:

Dog#1 12 25 2005

Dog#2 7 15 2003

Dog#3 9 24 2005

狗#4 1 1 2001

结果:

最老的是Dog#4 1/1/2001

最年轻的是狗#1 12/25/2005

5 个答案:

答案 0 :(得分:2)

您可以使用标准库中的日历/日期功能。但事实证明,如果没有它,您的问题也可以轻松回答:

  • 如果年出生的狗 A 出生的年龄小于 B 出生的那一年,那么 A 的狗会更老。
  • 如果狗 A B 出生在同一年,月狗 A 出生时少于月狗 B 出生然后狗 A 年纪久了。
  • 如果狗 A B 在同一年的同一个月出生,那么 A 出生的那天小于天狗 B 出生然后狗 A 年纪大了。
  • 如果狗 A B 在同一年的同一天出生,那么他们的年龄相同(给予或需要24小时)。

答案 1 :(得分:2)

我建议您使用Comparer来对狗的集合进行排序。看一下java.util.Comparator和java.lang.Comparable的javadoc

整数dogDay,dogMonth和dogYear是表示单个概念的部分,即狗的生日。因此,我建议你不要让狗分别拥有这三个整数,而是建议你定义一个类似日期的类。

class Dog {
  String dogName;
  Date dogBirthday;

现在,您可以在类似日期的类上定义排序。您可以通过实现Comparable接口来完成此操作。

class Date implements Comparable<Date> {
  final int day;
  final int month;
  final int year; 
  public Date(int day, int month, int year) {
    /* could check for invalid dates, e.g., 
    if (day < 1 || day > 31 || month < 1 || ...) {
      throw new InvalidArgumentException("Invalid date");
    } */
    this.day = day; this.month = month; this.year = year;
  }
  public int compareTo(Date other) {
    // Dates are comparable in lexicographic order
    int result = Integer(year).compareTo(Integer(other.year);
    if (result == 0) { result = Integer(month).compareTo(Integer(other.month)); }
    if (result == 0) { result = Integer(day).compareTo(Integer(other.day)); }
    return result;
  }
}

按日期订购,您可以按照他们的birhtday对狗的集合进行排序。

Collections.sort(dogs, 
  new Comparator<Dog>{
    int compare(Dog d1, Dog d2) { return d1.dogBirthday.compareTo(d2.dogBirthday);}
  };)

请注意,如果您打算实现Comparable,您还应该重写java.lang.Object的equals和hashCode方法(但是,您不受合同约束)。

关于我定义的Date类的附注:重用现有代码总是好的,所以定义你自己的Date类可能不是最好的事情。但是,我建议你不要使用java.util.Date,因为这个类完全坏了。如果我没有弄错的话,其中一个主要问题是它是可变的,这基本上与String可变是一样糟糕:你需要制作大量的防御性副本,否则你的代码可能会破坏可能很难调试的方式。如果您打算更广泛地使用日期并且使用的是Java 8,那么请使用新的Date and Time library。如果您使用的是旧版Java,我建议您查看Joda time

答案 2 :(得分:1)

通常情况下,我建议在使用日期时始终使用日历。这是因为日期变得非常复杂,如2月29日。 然而对于这种特定情况,您不需要日历API。

您目前遇到的问题是您将日期转换为字符串,然后比较字符串。不要这样做。比较字符串是不好的(它实际上并不像你期望的那样工作)。

你已经有了数字,所以为什么不使用它们呢?只需在你的狗类中放入月,日和年的getter方法。

然后你需要比较狗是一个简单的&#34;找到最小的数字&#34;方法。找到一年中最小的一个。如果这不起作用,那么比月份,如果那不起作用,那么。

public Dog youngestDog(List<Dog> dogs) {
    youngest = new Dog("Fake", 12, 31, 9999);
    for (dog : dogs) {
        if (dog.getYear() < youngest.getYear()) {
            youngest = dog;
        }
        else if (dog.getYear() == youngest.getYear()) {
            if (dog.getMonth() < youngest.getMonth()) {
                youngest = dog;
            }
            if (dog.getMonth() == youngest.getMonth()) {
                if (dog.getDay() <= youngest.getDay()) {
                    youngest = dog;
                }
            }
         }
    }
    return youngest;
}

注意:理想情况下,您实际上想要使用comparator or implement comparable,但这更高级,可能超出您的学习范围。

答案 3 :(得分:0)

  

1。将字段日历添加到您的狗类以替换月,日,年字段

     

2. 使用Calendar.setTime(Date)启动

     

3。使用Calendar.after或Calendar.before进行比较

答案 4 :(得分:0)

使用日期时间数据类型

是的,如果您正在使用日期时间数据,则应使用日期时间类型(类)。

避免java.util.Date

不幸的是,与Java捆绑的旧日期时间段(java.util.Date,.Calendar等)非常麻烦。避免他们。在许多其他问题中,他们缺乏表示仅限日期的方法,没有时间和时区,这是您所需要的。

而是使用Joda-Time库或Java 8捆绑的java.time包(受Joda-Time启发)。

比较

如其他答案中所述,我们必须实现一个比较器来到达Dog对象内部以检索并比较他/她的出生日期。

为了实际比较生日,我们称之为LocalDate比较方法:isBeforeisAfterisEqual

约达时间

与java.time一样,Joda-Time包含一个LocalDate类来表示没有任何时间或时区的仅限日期的值。

以下是Joda-Time 2.4中的一些示例代码。

package com.example.jodatimeexperiment;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.joda.time.LocalDate;

public class Dog
{
    // Member variables.
    String name = null;
    LocalDate birthDate = null;

    // Constructor
    public Dog( String nameArg , int yearArg , int monthArg , int dayOfMonthArg )
    {
        this.name = nameArg;
        this.birthDate = new LocalDate( yearArg , monthArg , dayOfMonthArg );
    }

    @Override
    public String toString()
    {
        return "Dog{" + "name=" + name + ", birthDate=" + birthDate + '}';
    }

    // Main method, to run this program.
    public static void main( String[] args )
    {
        List<Dog> list = new ArrayList<>();
        list.add( new Dog( "Alpha" , 2005 , 12 , 25 ) );
        list.add( new Dog( "Beta" , 2003 , 7 , 15 ) );
        list.add( new Dog( "Gamma" , 2005 , 9 , 24 ) );
        list.add( new Dog( "Delta" , 2001 , 1 , 1 ) );
        Collections.sort( list , new AgeComparator() );
        System.out.println( "Oldest: " + list.get( 0 ) ); // First item in list.
        System.out.println( "Youngest: " + list.get( list.size() - 1 ) ); // Last item in list.
    }

}

// Implement a Comparator.
class AgeComparator implements Comparator<Dog>
{

    @Override
    public int compare( Dog dog1 , Dog dog2 )
    {
        if ( dog1.birthDate.isAfter( dog2.birthDate ) ) {
            return 1;
        } else if ( dog1.birthDate.isBefore( dog2.birthDate ) ) {
            return -1;
        } else if ( dog1.birthDate.isEqual( dog2.birthDate ) ) {
            return 0;
        } else {
            // FIXME: Handle this supposedly impossible error condition.
            // Programmer made a mistake in logic or a typo in comparisons above.
            return -1; // Arbitrary choice of value to satisfy compiler.
        }

    }
}

跑步时。

Oldest: Dog{name=Delta, birthDate=2001-01-01}
Youngest: Dog{name=Alpha, birthDate=2005-12-25}

时区

可能不是你的家庭作业的一部分,但仅供参考,上面的示例代码假设所有的生日数据代表相同的时区。如果出生日期不代表同一时区,理想情况下,您将传入时区或偏离UTC。