android java 数组_关于android:Java按月将数组排列成多个数组

我在Java中有一个包含一组随机日期的数组:

{ January 20 2015, February 12 2015, February 20 2015, June 21 2015,

July 12 2015, July 28 2015, July 30 2015, September 24 2015, December 31 2015 }

如何按月将此数组拆分为多个数组?

我想要

{ {January 20 2015}, {February 12 2015, February 20 2015}, {June 21 2015},

{July 12 2015, July 28 2015, July 30 2015}, {September 24 2015}, {December 31 2015} }

我可以遍历整个数组并检查下一个日期是否仍然在同一个月内,然后将其添加到子数组中(如果是)。 但是我想知道是否有更简洁或有效的方法。

编辑:

此外,我需要按年份和月份排序,因此,例如,2014年1月15日和2015年1月23日不应合并。

这是我提出的一种方法,但它看起来效率不高:

private void splitListByMonth(){

ArrayList> mainArrayList = new ArrayList<>();

ArrayList titleList = new ArrayList<>();

Calendar calendar = Calendar.getInstance();

SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM yyy");

for(Homework homework:mList){

calendar.setTimeInMillis(homework.getDate());

String monthString = dateFormat.format(calendar.getTime());

if(titleList.contains(monthString)){

int index = titleList.indexOf(monthString);

mainArrayList.get(index).add(homework);

} else {

titleList.add(monthString);

int index = titleList.indexOf(monthString);

mainArrayList.get(index).add(homework);

}

}

Log.d("Tag",""+titleList);

Log.d("Tag",""+mainArrayList);

}

按月或按月/月? 例如。 应该Jan 15 2014和Jan 23 2015组合吗? 数组总是排序,还是日期可以按随机顺序排列?

也许你应该使用>的Map。 认为它会更好地为您服务。

为什么不使用像每个月0-11的List>这样的列表列表将对应于适当的索引,即所有带月份的日期都在索引0中。

是的,我同意,使用List>将极大地解决问题

但是,正如我在示例数组中所述,并非所有月份都需要。 例如,1月和2月出现,但未使用3月,4月和5月。

@Andreas我之前没有澄清过,但是我需要按年份和月份进行,因此2014年1月15日和2015年1月23日不应合并。 另外,我已经确定了日期。

@WayWay请通过编辑您的问题而不是发表评论来发布其他信息/说明。

你走在正确的轨道上,但是将年份/月份字母化是缓慢的方式,只需跟踪年份和月份:

@SuppressWarnings("null")

private static List> splitByMonth(Date ... dates) {

List> datesByMonth = new ArrayList<>();

List monthList = null;

int currYear = 0, currMonth = -1;

Calendar cal = Calendar.getInstance();

for (Date date : dates) {

cal.setTime(date);

if (cal.get(Calendar.YEAR) != currYear || cal.get(Calendar.MONTH) != currMonth) {

monthList = new ArrayList<>();

datesByMonth.add(monthList);

currYear = cal.get(Calendar.YEAR);

currMonth = cal.get(Calendar.MONTH);

}

monthList.add(date);

}

return datesByMonth;

}

请注意,参数必须预先排序。关于这一点,问题+评论有点不清楚。

测试代码

public static void main(String[] args) throws Exception {

// Build list of all dates

String[] txtDates = {"January 20 2015","February 12 2015","February 20 2015","June 21 2015",

"July 12 2015","July 28 2015","July 30 2015","September 24 2015","December 31 2015",

"January 15 2014","January 15 2015" };

SimpleDateFormat fmt = new SimpleDateFormat("MMMM d yyyy");

Date[] allDates = new Date[txtDates.length];

for (int i = 0; i < txtDates.length; i++)

allDates[i] = fmt.parse(txtDates[i]);

// Sort dates, then split them by month

Arrays.sort(allDates);

List> datesByMonth = splitByMonth(allDates);

// Print result

for (List dates : datesByMonth) {

StringBuilder buf = new StringBuilder();

for (Date date : dates) {

if (buf.length() != 0)

buf.append(",");

buf.append(fmt.format(date));

}

System.out.println(buf);

}

}

产量

January 15 2014

January 15 2015, January 20 2015

February 12 2015, February 20 2015

June 21 2015

July 12 2015, July 28 2015, July 30 2015

September 24 2015

December 31 2015

谢谢你的解释和指示!

乔达时间

对于Android,您应该使用Joda-Time库而不是旧的java.util.Date/.Calendar类,这些类已被证明是如此麻烦。请注意,Joda-Time的一些备用版本已经发布,以解决Android问题,最初的速度很慢。

Joda-Time包含一个YearMonth类,我们需要将年和月表示为跟踪日期值的关键。 Joda-Time还有一个LocalDate类来表示没有任何时间或时区的仅限日期的值。

我们定义一个格式为"MMMM dd yyyy"的格式化程序来解析字符串。请注意,我们在格式化程序上指定了一个具有英语语言的Locale,因此此代码将在JVM上成功运行,其中当前默认语言环境的语言不是英语。在解析月份"1月","2月"等的名称时,语言是否适用。

我们将LocalDate值收集为SortedSet,它实现了两个目的:(a)消除重复,以及(b)保持日期排序。我们SortedSet的实现是TreeSet。每个set对象都分配给YearMonth对象。 A TreeMap跟踪YearMonth具有哪组日期。我们使用TreeMap而不是HashMap来按键排序,因为它实现了SortedMap。如果你有大量的元素并且按键排序并不重要,那么HashMap可能是更好的性能选择。

String[] input = {"January 20 2015" ,"February 12 2015" ,"February 20 2015" ,"June 21 2015" ,"July 12 2015" ,"July 28 2015" ,"July 30 2015" ,"September 24 2015" ,"December 31 2015" };

Map> map = new TreeMap<>();

DateTimeFormatter formatter = DateTimeFormat.forPattern("MMMM dd yyyy" ).withLocale( Locale.ENGLISH );

for ( String string : input ) {

LocalDate localDate = formatter.parseLocalDate( string );

YearMonth yearMonth = new YearMonth( localDate );

if (  ! map.containsKey( yearMonth ) ) { // If this is the first encounter with such a year-month, make a new entry.

map.put( yearMonth , new TreeSet<>() );

}

map.get( yearMonth ).add( localDate );

}

转储到控制台。

System.out.println("input:" + Arrays.toString( input ) );

System.out.println("map:" + map );

跑步时

input: [January 20 2015, February 12 2015, February 20 2015, June 21 2015, July 12 2015, July 28 2015, July 30 2015, September 24 2015, December 31 2015]

map: {2015-01=[2015-01-20], 2015-02=[2015-02-12, 2015-02-20], 2015-06=[2015-06-21], 2015-07=[2015-07-12, 2015-07-28, 2015-07-30], 2015-09=[2015-09-24], 2015-12=[2015-12-31]}

java.time

在Java 8及更高版本中,您可以使用新的内置java.time框架。 Joda-Time为该框架提供了灵感。在本答案中,代码非常相似。

使用java 8 Collectors.groupingBy,它返回一个map,然后获取值toList。

List> partitions = dates.stream().collect(Collectors.groupingBy(e -> e.getYear() * 100 + e.getMonth(), TreeMap::new, Collectors.toList())).values().stream().collect(Collectors.toList());

问题标记为"Android",因此Java 8不可用。

但您仍然可以使用"e - > e.getYear()* 100 + e.getMonth()"方法对日期进行排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值