如何处理ResultSet每行重复创建Calendar/Date实例的问题
Great question! Creating new SimpleDateFormat and Calendar instances inside every iteration of your ResultSet loop is unnecessary and wastes system resources—let's break down the fixes step by step.
First: Fix the Old Java Date/Time API (Pre-Java 8)
The core issue here is that you're reinitializing objects that can easily be reused across loop iterations. Both SimpleDateFormat and Calendar are reusable; you just need to reset their state instead of creating new instances each time.
Here's the optimized code:
try { // Initialize reusable instances ONCE, outside the loop SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat dayFormatter = new SimpleDateFormat("EE"); Calendar calendar = Calendar.getInstance(); ResultSet rs = DBHelper.st.executeQuery("SELECT date FROM days ORDER BY date ASC;"); while (rs.next()) { // Parse the date string once and reuse the Calendar instance Date date = dateParser.parse(rs.getString(1)); calendar.setTime(date); // Format the day using the reusable formatter String dayOfWeek = dayFormatter.format(calendar.getTime()); System.out.println(dayOfWeek + ", " + rs.getString(1).substring(8)); } } catch(SQLException | ParseException ex) { ex.printStackTrace(); }
Important Note: Thread Safety
Keep in mind that SimpleDateFormat and Calendar are not thread-safe. If this code will run in a multi-threaded environment (like a web application), you have two options:
- Wrap usage in a
synchronizedblock (can hurt performance) - Use
ThreadLocalto create an instance per thread
Better: Use Java 8+ java.time API (Recommended)
The old date/time APIs are outdated, error-prone, and not thread-safe. Java 8 introduced the java.time package (JSR-310), which solves these problems entirely. DateTimeFormatter is thread-safe, and classes like LocalDate are immutable and easy to work with.
Here's the modernized version:
try { // Thread-safe formatters, initialized once DateTimeFormatter dateParser = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("EE"); ResultSet rs = DBHelper.st.executeQuery("SELECT date FROM days ORDER BY date ASC;"); while (rs.next()) { String dateStr = rs.getString(1); // Parse directly to LocalDate (immutable, no state to reset) LocalDate date = LocalDate.parse(dateStr, dateParser); // Format the day of the week String dayOfWeek = date.format(dayFormatter); System.out.println(dayOfWeek + ", " + dateStr.substring(8)); } } catch(SQLException ex) { ex.printStackTrace(); }
Bonus: Direct JDBC LocalDate Retrieval
If you're using a JDBC 4.2+ compliant driver (most modern drivers are), you can skip string parsing entirely and fetch the date directly as a LocalDate:
// Replace the parse step with this: LocalDate date = rs.getObject(1, LocalDate.class);
This is even more efficient and avoids potential parsing errors.
Key Takeaways
- Reuse objects when possible: Avoid creating instances of heavy objects like formatters or calendars inside loops.
- Prefer
java.time: It's safer, more readable, and designed for modern Java applications. - Watch thread safety: Old date/time classes aren't thread-safe—plan accordingly if using them in multi-threaded code.
内容的提问来源于stack exchange,提问作者Diabolic Vincent

