而不是多个if语句Java日期

时间:2018-06-25 23:41:02

标签: java if-statement

有没有比编写多个if语句更好的方法了?

我正在解析文档以查找日期实例,如果发生实例,则增加int值。

public class OrganisingData {

    static int jan16=0;
    static int feb16=0;
    static int mar16=0;//... static int dec18

    public static void Months(String dates) {
        if (dates.substring(2, 4).equals("16") && 
            dates.substring(5,7).equals("01")) {
            jan16++;
        }
        if (dates.substring(2, 4).equals("16") && 
            dates.substring(5,7).equals("02")) {
            feb16++;...
        }
        if (dates.substring(2, 4).equals("18") &&
            dates.substring(5,7).equals("12")) {
            dec18++;
        }
    }
}

我正在尝试构建条形图,jan16 feb16等代表月份和年份,每当我发现坚持该日期(例如2016年1月15日)时,我都会增加jan16。因此,与其写每个月+年的多个if语句(总共32个if语句),不如编写一个更好的方法吗?

5 个答案:

答案 0 :(得分:4)

基本上是@John T和@Zachary所说的混合,但是具有正确的语法和类型转换。

// [Years] and [Months], where [0][0] is jan 2000. May need to adjust for previous years.
int[][] days = new int[30][12];

void month(String dates) {
    int year = Integer.parseInt(dates.substring(2, 4)); 
    int month = Integer.parseInt(dates.substring(5,7)) - 1;

    days[year][month]++;
}

答案 1 :(得分:1)

您可以使用setTag()来减少笨拙的逻辑,尽管这不一定会造成很大的冷凝。您将需要使用switch statement或将日/月值转换为整数。

String day = dates.substring(2, 4);
String month = dates.substring(5, 7);

switch (month) {
    case "01" : {
        if (day.equals("16"))
            jan16++;
        break;
    }
}

如果要执行的操作背后有某种模式,则可能会有更好的解决方案。例如,以下内容将算作每月的16号

int count[] = new int[12];
  ...
int day = Integer.parseInt(dates.substring(2, 4));
int month = Integer.parseInt(dates.substring(5, 7));


if (day == 16)
    count[month - 1]++;

答案 2 :(得分:1)

YearMonth

显然您要跟踪年月值。为此有一个类,名为YearMonth。在 java.time 包中找到此类,该软件包取代了与最早的Java版本捆绑在一起的非常麻烦的旧日期时间类。

MonthDay

或者您正在拍摄月日值;您的问题很复杂,所以我不确定您的目标。但是,如果这是您的目标,那么又有一个针对该类的课程:MonthDay

Month

或者也许您只想要一个月而不管年份或月份的哪一天,在这种情况下,您可以使用Month类。

LocalDate

如果输入字符串表示年,月,日,请解析为LocalDate。该课程没有课程,没有时区。

LocalDate ld = LocalDate.parse( "2016-01-15" ) ;

提取YearMonthMonthDayMonth

YearMonth ym = YearMonth.from( ld ) ;

创建一个集合。也许您想在特定的月份中保留所有LocalDate对象的所有不同集合。如果是这样,请创建一个Map,其中每个YearMonth对象都拥有Set个对象的LocalDate

Map < YearMonth, Set < LocalDate > > map = new HashMap <>();

在处理每个输入日期时,请检查地图是否具有针对特定输入YearMonth创建的Set。如果不是,请实例化TreeSetTreeSet类是SortedSet,这意味着在您添加值时它会保持排序顺序。

Set < LocalDate > set = map.get( ym );
if ( null == set ) {
    set = new TreeSet <>(); // A `TreeSet` is a `SortedSet`, maintains a sorted order. You may or may not need this behavior.
    map.put( ym , set );
}

手持Set,添加您的LocalDate

set.add( ld );

处理后,您可以从YearMonth获取Map键的集合。并且对于每一个,您都可以检索其拥有的Set,并获得其中包含的元素的计数。

Lamba和流

对于较短的代码,您也许可以将Lambda语法和流与Map::computeIfAbsent一起使用。我已经看过这种代码,但是还没有尝试过。

map.computeIfAbsent( key , k -> new TreeSet< LocalDate >() ).add( ld ) ;

仅计数

如果只希望计数,而不关心LocalDate的值,请将Set替换为“ value”,或者将Map替换为Integer对象。与其检索Set并将其添加,不如检索Integer并通过添加一个使其递增。就个人而言,在这种情况下,我发现最好收集LocalDate值以进行调试/测试和/或在其他业务逻辑中进一步使用。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 3 :(得分:0)

使用适当的数据结构,您可以大大减少此代码。 想法是要有一个数据结构,该结构对于您感兴趣的每一年都包含一个整数数组:每个月一个。

然后,将子串从dates字符串转换为数字,您可以使用这些数字来索引数据结构。

import java.util.Map;
import java.util.HashMap;

private static Map<Integer, int[]> years = new HashMap<>();
private static String[] monthNames = new String[] {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

static {
    for(int year = 16; year <= 18; year++) {
        years.put(year, new int[12]);
    }
}

public static void months(String dates) { // method names should start with lower case
    int year = Integer.parseInt(dates.substring(2, 4));
    int month = Integer.parseInt(dates.substring(5, 7)) - 1; // date String is one-based, array-index is zero-based
    years.get(year)[month]++;
}

public static void print() {
    for(int year = 16; year <= 18; year++) {
        int[] monthCounts = years.get(year);
        for(int month = 0; month < 12; month++) {
            System.out.println(monthNames[month] + " " + year + ": " + monthCounts[month]);
        }
    }
}

您可以看到运行中的代码here

答案 4 :(得分:-2)

在文档中浏览以下内容:

// 18 years(more needed?), 12 months
String[][] yearsAndMonths = new String[18][12];  

yearsAndMonths[dates.substring(5,7)][dates.substring(2, 4)]++;

然后打印结果。

我不是Java专家。刚刚提供的代码为您提供了逻辑。