如何将月份放入每个数组中?

huangapple go评论89阅读模式
英文:

How do I put months in each array?

问题

我正在制作一个用于统计一个月内花费的程序;然而,我不知道在for循环中应该做什么,以便使其按正确顺序使用相应的月份名称初始化每个MonthlyExpensePeriods

for (int i = 0; i < 12; i++) {
    monthlyExpensePeriods[i] = new MonthlyExpensePeriods(月份名称);
}
英文:

I'm making a program for expense statistics over a month; however, I don't know what I should do in the for loop in order to make it initialize each MonthlyExpensePeriods with the corresponding name of that month in the correct order?

for(int i = 0; i &lt; 12; i++){ 
    monthlyExpensePeriods[i] = new MonthlyExpensePeriods(month&#39;s name); 
}

答案1

得分: 1

你可以使用 DateFormatSymbols.getMonths() 方法:

String[] monthNames = new DateFormatSymbols().getMonths();
for (int i = 0; i < 12; i++) {
    monthlyExpensePeriods[i] = new MonthlyExpensePeriods(monthNames[i]);
}
英文:

You could use DateFormatSymbols.getMonths():

String[] monthNames = new DateFormatSymbols().getMonths();
for(int i = 0; i &lt; 12; i++){ 
    monthlyExpensePeriods[i] = new MonthlyExpensePeriods(monthNames[i]); 
}

答案2

得分: 1

# tl;dr

使用`Month`枚举对象而不是仅仅使用月份名称的文本

    for(int i = 1; i <= 12; i++){ 
        monthlyExpensePeriods[i] = new MonthlyExpensePeriod( Month.of( i ) ); 
    }

# 使用智能对象而不是愚蠢的字符串

对于特殊值例如追踪一年中的每个月份),使用字符串是脆弱且容易出错的

# `Month`

相反使用对象

在Java 8及更高版本中我们内置了[`Month`][1]枚举类此枚举预定义了十二个对象每个对象代表一年中的一个月并分配了命名常量

你的类`MonthlyExpensePeriod`应该持有一个类型为`Month`的成员变量

    public class MonthlyExpensePeriod {
        // 成员字段
        public Month month ;
        

        // 构造函数
        public MonthlyExpensePeriod( final Month monthArg ) {
            this.month = monthArg ;
            
        }
    }

要使用该类及其构造函数传递其中一个命名常量

    new MonthlyExpensePeriod ( Month.MARCH )

你可以通过月份编号检索`Month`对象之一请注意合理的编号1到12分别代表一月到十二月

    Month month = Month.of( 3 ) ;  // Month.MARCH

因此你的示例代码将如下所示将你的`for`循环改为计数1到12

    for(int i = 1; i <= 12; i++){ 
        monthlyExpensePeriods[i] = new MonthlyExpensePeriod( Month.of( i ) ); 
    }

## 集合

你可能希望使用[Java集合][2]而不是仅仅使用数组

    List< MonthlyExpensePeriod > periods = new ArrayList<>( 12 ) ;
    for(int i = 1; i <= 12; i++){ 
        MonthlyExpensePeriod period = new MonthlyExpensePeriod( Month.of( i ) ) ;
        periods.add( period ); 
    }

## 流式处理

我想我们可以使用流式处理来变得更加高级但在这种情况下我没有看到任何附加价值

调用[`Month.values()`][3]返回一个数组其中包含按照定义顺序排列的所有枚举对象我们可以通过调用实用类方法[`Arrays.stream`][4]生成一个流

    List < MonthlyExpensePeriod > periods =
            Arrays.stream( Month.values() )
                    .map( month -> new MonthlyExpensePeriod( month ) )
                    .collect( Collectors.toList() )
    ;
 

或者作为单行代码

    List < MonthlyExpensePeriod > periods = Arrays.stream( Month.values() ).map( month -> new MonthlyExpensePeriod( month ) ).collect( Collectors.toList() );

你可能希望创建一个不可修改的副本列表

    List < MonthlyExpensePeriod > periodsUnmod = List.copyOf( periods );

或者通过调用`Collectors.toUnmodifiableList()`将原始列表设置为不可修改详情请参阅[这里的讨论][5]

    List < MonthlyExpensePeriod > periods = 
            Arrays
            .stream( Month.values() )
            .map( month -> new MonthlyExpensePeriod( month ) )
            .collect( Collectors.toUnmodifiableList() )
    ;

## 生成显示文本

你可能希望显示月份的名称

调用`Month::toString`会生成全大写的英文名称文本但你可以自动进行本地化处理

要进行本地化处理传递一个[`TextStyle`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/TextStyle.html)对象,以指示你希望名称的长度或缩写程度。请注意,`TextStyle`提供了`STANDALONE`变体,用于某些语言(不是英语),其中月份名称出现在日期上下文之外。

并传递一个`Locale`来确定用于本地化的人类语言和文化规范

    Locale locale = Locale.CANADA_FRENCH ;  // 或 Locale.US 等等。
    String output = Month.MARCH.getDisplayName( TextStyle.FULL , locale ) ;

  [1]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Month.html
  [2]: https://en.wikipedia.org/wiki/Java_collections_framework
  [3]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Month.html#values()
  [4]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Arrays.html
  [5]: https://stackoverflow.com/q/61132631/642706
英文:

tl;dr

Use Month enum objects rather than mere text of name of month.

for(int i = 1; i &lt;= 12; i++){ 
monthlyExpensePeriods[i] = new MonthlyExpensePeriod( Month.of( i ) ); 
}

Use smart objects, not dumb strings

Using strings for special values, such as tracking each month of the year, is fragile and error-prone.

Month

Instead, use objects.

In Java 8 and later, we have the Month enum class built-in. This enum predefines a dozen objects, one for each month of the year, each assigned to a named constant.

Your class MonthlyExpensePeriod should hold a member variable of type Month.

public class MonthlyExpensePeriod {
// Member fields
public Month month ;
…
// Constructor
public MonthlyExpensePeriod( final Month monthArg ) {
this.month = monthArg ;
…
}
}

To use that class and its constructor, pass one of the named constants.

new MonthlyExpensePeriod ( Month.MARCH )

You can retrieve one of the Month objects by month number. Notice the sane numbering, 1-12 for January-December.

Month month = Month.of( 3 ) ;  // Month.MARCH

So your example code would look like the following. Change your for loop to count 1-12.

for(int i = 1; i &lt;= 12; i++){ 
monthlyExpensePeriods[i] = new MonthlyExpensePeriod( Month.of( i ) ); 
}

Collections

You may want to use Java Collections rather than mere arrays.

List&lt; MonthlyExpensePeriod &gt; periods = new ArrayList&lt;&gt;( 12 ) ;
for(int i = 1; i &lt;= 12; i++){ 
MonthlyExpensePeriod period = new MonthlyExpensePeriod( Month.of( i ) ) ;
periods.add( period ); 
}

Streams

I suppose we could get fancy and use streams. But in this case I do not see any added-value.

Calling Month.values() returns an array of all the objects defined on the enum, in the order in which they were defined. From that, we can generate a stream by calling the utility class method Arrays.stream.

List &lt; MonthlyExpensePeriod &gt; periods =
Arrays.stream( Month.values() )
.map( month -&gt; new MonthlyExpensePeriod( month ) )
.collect( Collectors.toList() )
;

Or as a single-line of code.

List &lt; MonthlyExpensePeriod &gt; periods = Arrays.stream( Month.values() ).map( month -&gt; new MonthlyExpensePeriod( month ) ).collect( Collectors.toList() );

You might want to make an unmodifiable copy of your list.

List &lt; MonthlyExpensePeriod &gt; periodsUnmod = List.copyOf( periods );

Or make the original list unmodifiable, by calling Collectors.toUnmodifiableList(), as discussed here.

List &lt; MonthlyExpensePeriod &gt; periods = 
Arrays
.stream( Month.values() )
.map( month -&gt; new MonthlyExpensePeriod( month ) )
.collect( Collectors.toUnmodifiableList() )
;

Generating display text

You may want to display the name of the month.

Calling Month::toString generates text of the name in English in all caps. Instead you can automatically localize.

To localize, pass a TextStyle object to signal how long or abbreviated you want the name. Notice that TextStyle offers STANDALONE variations used in some languages (not English) where the month name appears outside the context of a date.

And pass a Locale to determine the human language and cultural norms to use in localizing.

Locale locale = Locale.CANADA_FRENCH ;  // Or Locale.US and so on.
String output = Month.MARCH.getDisplayName( TextStyle.FULL , locale ) ;

huangapple
  • 本文由 发表于 2020年4月10日 05:46:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/61130736.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定