【问题标题】:Determining which of two events is nearer?确定两个事件中的哪一个更接近?
【发布时间】:2018-08-28 11:26:35
【问题描述】:

我想知道哪个活动更近。

现在,我编写的代码依赖于比较,而且似乎并非每次都有效。

与我尝试做的所有事情一样,我想要一个既干净又高效的解决方案(请随意批评我的代码)。

活动有一个特定的时间(例如 16:00),提示如何添加此级别的详细信息会很好。

代码如下:

public static int getNextEvent() 
{

    int event1 = 2; //Those events happen every week and have specific
                    //hours (didn't implement those because I have no
                    //idea how to, suggestions are greatly appreciated here)
    int event2 = 6;
    int result = 0;
    int currentDay = 6; //Days go from monday (1) to sunday (7), here this is hardcoded, in the actual program it is not.
    List<Integer> eventList = new ArrayList<Integer>();

    if (currentDay <= event1) //This is the comparison I was talking about
    { 
        eventList.add((event2-currentDay)); // These two are in this specific order because I use the indexOf for later methods (yes, those events are hardcoded, that's fine)
        eventList.add((event1-currentDay)); //
    }
    else
    {
        currentDay = currentDay - 7;
        eventList.add((event2-currentDay)); // These two are in this
                                            // specific order because
                                            // I use the indexOf for
                                            // later methods (yes,
                                            // those events are
                                            // hardcoded, that's fine)
        eventList.add((event1-currentDay)); //
    }

    result = determineClosestEvent(eventList) + 1; // I add 1 because my other methods 
                                                   //do not start at 0 but at 1 
                                                   //(see ^ that comment)

    return result;
}

private static int determineClosestEvent(List<Integer> eventList) 
{

    int closestDay = 10;
    int listGet;

    for (int i = 0; i < eventList.size(); i++) 
    {
        listGet = eventList.get(i);
        if (closestDay > listGet) 
        {
            closestDay = listGet;
        } else {}
    }

    closestDay = eventList.indexOf(closestDay);

    return closestDay;
}

【问题讨论】:

  • 我不知道这是赋值还是什么,但如果这段代码中的一切都取决于你,你绝对应该使用为此目的而制作的结构,例如GregorianCalendar
  • @ArthurAttout,我想到了,问题是事件不是一次性的(我不能真正硬编码日期)。
  • 你是什么意思,“不是一次性的事情”? GregorianCalendar 中有很多构造函数,其中一个可能就是你要找的
  • 如果您的编译器支持 java 8,我建议不要使用 GregorianCalendar,并查看 java.time 包,它提供了非常有用的日期和时间处理方法
  • "确定两个事件中哪一个更接近?" 更接近什么?

标签: java time


【解决方案1】:

为您的活动设计一个Event 类。使用 DayOfWeek(来自 java.time,现代 Java 日期和时间 API)作为事件的星期几,LocalTime 作为一天中的时间。

要了解每个事件的过去或未来有多远,首先使用ZonedDateTime.now(yourTimeZone) 确定当前日期和时间。鉴于 currentDateTimeZonedDateTime,请使用 currentDateTime.toLocalDate().getDayOfWeek() 获取今天的星期几。

对于每个事件,如果今天没有发生,请同时考虑上一次和下一次(如果根据您的要求这是合适的)。使用TemporalAdjusters.previous()TemporalAdjusters.next() 查找日期。然后LocalDate.atTimeLocalDateTime.atZone 得到ZonedDateTime 事件发生或发生的时间。现在您有一个用于当前时间的ZonedDateTime 和一个用于事件时间的Duration.between() 来查找此事件的过去或未来有多远。您可能希望Duration.abs() 确保持续时间为非负数。和Duration.compareTo 用于确定哪个持续时间更短。那里有最近的活动。

链接

【讨论】:

    【解决方案2】:

    不关心公共/私人问题:

    import java.util.*;
    

    /* 您可以通过将代码复制到一个名为 EventTest 的大文件中来测试代码。您可以缩进 cmets,或删除它们。为了更好的可读性,我在这里取消了它们的缩进。看看Interface Comparable,一个非常有用的接口,因为如果你定义了这样一个方法,你可以用Java方法对这样的东西的Collection进行排序。 */

    class MyDate implements Comparable <MyDate> {
    

    /* 只是一个简单的 int 星期几,就像你的尝试一样。 */ int 道;

        public MyDate (int dow)
        {
            this.dow = dow;
        }
    
        // if other date is over, next date is in next week - add 7.
        public int compareTo (MyDate other) {
            int diff = other.dow - dow;
            if (diff < 0) diff += 7;
            return diff;
        }
    
        public String toString () {
            return "" + dow;
        }
    }
    

    /* 一个事件有一个日期 - 让我们也有一个名字: */

    class Event {
        String name;
        public MyDate dow;
    
        public Event (String name, MyDate dow)
        {
            this.dow = dow;
            this.name = name;
        }
    

    /* 为了以后的使用,我们提供了一个 dateDiff 方法,它将日期的比较委托给 dow.compareTo 方法: */

        public int dateDiff (MyDate cmp) {
            return dow.compareTo (cmp);
        }
    
        public String toString () {
            return name + " " + dow;
        }
    }
    

    /* 我们需要一个额外的比较器,将不同的事件与外部给定的 MyDate 进行比较。 */

    class EventComparator implements Comparator <Event>
    {
        MyDate crucialDate;
        public EventComparator (MyDate crucial)
        {
            crucialDate = crucial;
        }
        public int compare (Event e1, Event e2)
        {
            int diff = (e1.dateDiff (crucialDate)) - (e2.dateDiff (crucialDate));
            return diff;
        }
    }
    

    /* 现在是脂肪测试班。 */

    public class EventTest {
    

    /* 在测试 testMany() 方法之前,首先尝试了解 test2 方法的工作原理。 */

        public static void main(String[] args) {
            test2 ();
            // testMany ();
        }
    

    /* Comparator 在这里有它的重要时刻。好吧 - 它为给定的 MyDate 'current' 事件列表排序。如果列表不为空,则第一个元素是最接近的(其中一个)。 */

        static List<Event> findClosest (MyDate current, List<Event> events) {
            EventComparator ec = new EventComparator (current);
            events.sort (ec);
            return events;
        }
    

    /* 如您的示例中所示,2 个日期 (2, 6) 和一个 currentDay (6)。 事件列表已到位并包含相同的元素,可能以不同的顺序: */
    静态无效测试2(){ 列表事件列表 = 新的 ArrayList (); eventList.add(new Event("Dow: 2", new MyDate(2))); eventList.add(new Event("Dow: 6", new MyDate(6))); MyDate currentDay = new MyDate (6); System.out.println("未排序"); 显示(事件列表); System.out.println("排序"); findClosest (currentDay, eventList); 显示(事件列表); }

        static void testMany () {
            Random r = new Random ();
            // eventList.add (new Event ("Dow: " + day, new MyDate (day)));
            List<Event> eventList = new ArrayList<> ();
            for (int i = 0; i < 10; ++i) {
                int day = r.nextInt (7) + 1;
                eventList.add (new Event ("Dow: " + day, new MyDate (day)));
            }
            for (int today = 1; today <= 7; ++today) {
                MyDate currentDay = new MyDate (today);
                System.out.println ("unsorted " + currentDay);
                show (eventList);
                findClosest (currentDay, eventList);
                System.out.println ("sorted "+ currentDay);
                show (eventList);
            }
        }
    
        public static void show (List <Event> events) {
            for (Event e : events)
                System.out.println (e);
        }
    }
    

    您以后可以扩展 MyDate 类以包含小时数。从语义上讲,我没有检查算法是否按预期工作。你应该先写一些测试用例

    • 比今天早 2 个日期
    • 先低后高
    • 先高后低
    • 都比今天高
    • 不同的距离,相同的距离,
    • 与当前日期相同

    做一个小表格,先把预期的结果写下来,然后看看是否有效。

    【讨论】:

      猜你喜欢
      • 2022-12-03
      • 2015-01-12
      • 1970-01-01
      • 2019-04-22
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      相关资源
      最近更新 更多