У вас тяжелая работа. Теперь вы можете просто использовать Map
для подсчета вхождений:
Map<String, Integer> occurrences = new HashMap<String, Integer>();
for ( String word : splitWords ) {
Integer oldCount = occurrences.get(word);
if ( oldCount == null ) {
oldCount = 0;
}
occurrences.put(word, oldCount + 1);
}
Используя map.get(word)
, вы будете много раз говорить о слове. Вы можете построить новый список, итерации через map.keySet()
:
for ( String word : occurrences.keySet() ) {
//do something with word
}
Обратите внимание, что порядок того, что вы получаете из keySet
, произволен. Если вам нужны слова для сортировки, когда они впервые появляются в вашей строке ввода, вы должны использовать вместо этого LinkedHashMap
.
К сожалению, форматы часовых поясов, доступные для SimpleDateFormat (Java 6 и более ранние версии), не соответствуют ISO 8601 . SimpleDateFormat понимает такие строки часовых поясов, как «GMT + 01: 00» или «+0100», последнее в соответствии с RFC # 822 .
Даже если в Java 7 добавлена поддержка дескрипторов часовых поясов в соответствии с ISO 8601, SimpleDateFormat по-прежнему не может правильно анализировать полную строку даты, поскольку не поддерживает дополнительные части.
Переформатирование входной строки с помощью регулярного выражения, безусловно, является одной из возможностей, но правила замены не так просты, как в вашем вопросе:
Возможно, более простым решением является использование преобразователя типов данных в JAXB, поскольку JAXB должен иметь возможность анализировать строку даты ISO8601 в соответствии со спецификацией схемы XML. javax.xml.bind.DatatypeConverter.parseDateTime ("2010-01-01T12: 00: 00Z")
предоставит вам объект Calendar
, и вы можете просто использовать для него getTime (), если вам нужен Дата
объекта.
Вы, вероятно, могли бы также использовать Joda-Time , но я не знаю, зачем вам это нужно.
Вот является Kotlin базирующимся подходом с помощью Java 7. Можно передать пользовательские шаблоны или просто использовать шаблон ISO8601 по умолчанию. Вероятно, необходимо обработать ошибки анализа все же.
object DateUtil {
private const val ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSX"
fun convertDateToTimestamp(date: Date, pattern: String = ISO_8601_PATTERN): String {
val df = SimpleDateFormat(pattern, Locale.getDefault()).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
return df.format(date)
}
fun convertTimestampToDate(timestamp: String, pattern: String = ISO_8601_PATTERN): Date {
val formatter = SimpleDateFormat(pattern, Locale.getDefault()).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
return formatter.parse(timestamp) ?: Date(0)
}
}
Немного теста, который показывает, как проанализировать дату в ISO8601 и что LocalDateTime не обрабатывает DSTs.
@Test
public void shouldHandleDaylightSavingTimes() throws ParseException {
//ISO8601 UTC date format
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
// 1 hour of difference between 2 dates in UTC happening at the Daylight Saving Time
Date d1 = utcFormat.parse("2019-10-27T00:30:00.000Z");
Date d2 = utcFormat.parse("2019-10-27T01:30:00.000Z");
//Date 2 is before date 2
Assert.assertTrue(d1.getTime() < d2.getTime());
// And there is 1 hour difference between the 2 dates
Assert.assertEquals(1000*60*60, d2.getTime() - d1.getTime());
//Print the dates in local time
SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm z Z", Locale.forLanguageTag("fr_CH"));
localFormat.setTimeZone(TimeZone.getTimeZone("Europe/Zurich"));
//Both dates are at 02h30 local time (because of DST), but one is CEST +0200 and the other CET +0100 (clock goes backwards)
Assert.assertEquals("2019-10-27 02:30 CEST +0200", localFormat.format(d1));
Assert.assertEquals("2019-10-27 02:30 CET +0100", localFormat.format(d2));
//Small test that shows that LocalDateTime does not handle DST (and should not be used for storing timeseries data)
LocalDateTime ld1 = LocalDateTime.ofInstant(d1.toInstant(), ZoneId.of("Europe/Zurich"));
LocalDateTime ld2 = LocalDateTime.ofInstant(d2.toInstant(), ZoneId.of("Europe/Zurich"));
//Note that a localdatetime does not handle DST, therefore the 2 dates are the same
Assert.assertEquals(ld1, ld2);
//They both have the following local values
Assert.assertEquals(2019, ld1.getYear());
Assert.assertEquals(27, ld1.getDayOfMonth());
Assert.assertEquals(10, ld1.getMonthValue());
Assert.assertEquals(2, ld1.getHour());
Assert.assertEquals(30, ld1.getMinute());
Assert.assertEquals(0, ld1.getSecond());
}