30+ Java Refactoring Tricks to Write Cleaner, Faster Code

This article presents a comprehensive collection of Java code‑simplification techniques—from ternary operators and enhanced for‑loops to streams, Optional, design patterns, and aggressive dead‑code removal—showing how each shortcut can reduce boilerplate, improve readability, and boost performance in backend development.

Programmer DD
Programmer DD
Programmer DD
30+ Java Refactoring Tricks to Write Cleaner, Faster Code

1. Use Ternary Expressions

Replace verbose if‑else assignments with concise ternary operators.

String title = isMember(phone) ? "会员" : "游客";

2. Use Enhanced For‑Each Loops

Iterate over arrays or collections without manual index handling.

for (double value : values) {
    // TODO: process value
}

3. Use try‑with‑Resources

Automatically close resources that implement Closeable.

try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        // TODO: process line
    }
} catch (IOException e) {
    log.error("读取文件异常", e);
}

4. Return Early with return

Eliminate intermediate variables by returning directly.

public boolean hasSuper(@NonNull List<UserDO> userList) {
    for (UserDO user : userList) {
        if (Boolean.TRUE.equals(user.getIsSuper())) {
            return true;
        }
    }
    return false;
}

5. Apply static Keyword

Make utility methods and constants static to avoid object creation.

public final class GisHelper {
    public static double distance(double lng1, double lat1, double lng2, double lat2) {
        // calculation
    }
}

6. Leverage Lambda Expressions

Replace anonymous inner classes with lambdas for brevity.

new Thread(() -> {
    // thread logic
}).start();

7. Use Method References

Further shorten lambdas when they merely forward a call.

List<Long> ids = users.stream()
    .map(UserDO::getId)
    .collect(Collectors.toList());

8. Static Imports

Import static members to drop class qualifiers.

import static java.lang.Math.PI;
import static java.lang.Math.pow;
double area = PI * pow(radius, 2);

9. Unchecked Exceptions

Wrap checked exceptions in runtime ones to avoid repetitive throws declarations.

public void setLong(PreparedStatement stmt, int idx, Long val) throws SQLException {
    if (val != null) {
        stmt.setLong(idx, val);
    } else {
        stmt.setNull(idx, Types.BIGINT);
    }
}

10. Annotation Shortcuts

Use Lombok to generate boilerplate, Validation for constraints, and @NonNull to express required parameters.

@Getter @Setter @ToString
public class UserVO {
    private Long id;
    private String name;
}

11. Generic Techniques

Introduce type parameters to eliminate duplicated code for different data types.

public interface Comparable<T> {
    int compareTo(T other);
}

public class Point<T extends Number> {
    private T x;
    private T y;
}

12. Constructor Overloads

Use @AllArgsConstructor and @NoArgsConstructor to create objects in a single line.

return new PageDataVO<>(totalCount, userList);

13. Set add Return Value

Use the boolean result of Set.add to replace a separate contains check.

if (userIdSet.add(userDO.getId())) {
    userVOList.add(transUser(userDO));
}

14. Map computeIfAbsent

Replace manual map‑initialisation with computeIfAbsent.

roleUserMap.computeIfAbsent(userDO.getRoleId(), k -> new ArrayList<>())
    .add(userDO);

15. Chain Calls

Build objects via method chaining for fluent APIs.

StringBuilder sb = new StringBuilder(96)
    .append("select id, name from ")
    .append(T_USER)
    .append(" where id = ")
    .append(userId)
    .append(";");

16. Array‑Based Simplifications

Use IntStream to generate numeric sequences.

int[] range = IntStream.rangeClosed(1, N).toArray();
int[] powers = IntStream.iterate(1, n -> n * 2).limit(N).toArray();

17. Data‑Structure Helpers

Employ ThreadLocal for per‑thread objects, Optional for null‑safe handling, and container classes like Pair or Triple to return multiple values.

ThreadLocal<DateFormat> fmt = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd"));
String dateStr = fmt.get().format(date);

18. Optional Usage

Replace explicit null checks with Optional pipelines.

Integer thisValue = Optional.ofNullable(value).orElse(DEFAULT_VALUE);
String zip = Optional.ofNullable(user)
    .map(User::getAddress)
    .map(Address::getCountry)
    .map(Country::getZipcode)
    .orElse(null);

19. Stream API Patterns

Common stream patterns for matching, filtering, aggregation, mapping, grouping, and range generation.

// Match
boolean found = userList.stream().anyMatch(u -> Objects.equals(u.getId(), userId));

// Filter
List<UserDO> superUsers = userList.stream()
    .filter(u -> Boolean.TRUE.equals(u.getIsSuper()))
    .collect(Collectors.toList());

// Sum
double total = accountList.stream().mapToDouble(Account::getBalance).sum();

// Map conversion
List<UserVO> voList = userDOList.stream()
    .map(this::transUser)
    .collect(Collectors.toList());

// Grouping
Map<Long, List<UserDO>> byRole = userDOList.stream()
    .collect(Collectors.groupingBy(UserDO::getRoleId));

// Group‑and‑sum
Map<Long, Double> roleTotal = accountList.stream()
    .collect(Collectors.groupingBy(Account::getRoleId, Collectors.summingDouble(Account::getBalance)));

// Range generation
int[] nums = IntStream.rangeClosed(1, N).toArray();

20. Program‑Structure Clean‑ups

Return boolean expressions directly, minimise the scope of conditionals, and place expressions where they reduce duplication.

public boolean isSuper(Long userId) {
    UserDO user = userDAO.get(userId);
    return Objects.nonNull(user) && Boolean.TRUE.equals(user.getIsSuper());
}

String message = result.isSuccess() ? "上报工作日报成功" : "上报工作日报失败:" + result.getMessage();
log.warn(message);
dingtalkService.sendMessage(user.getPhone(), message);

21. Design‑Pattern Refactorings

Apply the Template Method pattern to share Redis key handling, replace verbose builder interfaces with functional parameters, and use @ControllerAdvice or AOP for centralized exception handling.

// Template method example
public abstract class AbstractDynamicValue<I, V> {
    @Resource(name="stringRedisTemplate")
    private ValueOperations<String, String> ops;
    public void set(I id, V val) { ops.set(key(id), JSON.toJSONString(val)); }
    public V get(I id) { return JSON.parseObject(ops.get(key(id)), valueClass()); }
    protected abstract String key(I id);
    protected abstract Class<V> valueClass();
}

22. Aggressive Dead‑Code Removal

Delete unused imports, redundant public modifiers in interfaces, unnecessary private on enum constructors, final on methods of final classes, superfluous implements clauses, and variables that merely forward a call.

// Before
public interface UserDAO { public Long countUser(...); }
// After
public interface UserDAO { Long countUser(...); }

The above collection of shortcuts and refactorings enables Java developers to write more concise, maintainable, and performant backend code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformanceCode Refactoringclean code
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.