Java Development Tips and Examples
Java 8 Stream Operatinos
// Extract a specific property list from a collection
List<String> taskIds = taskList.stream().map(TaskItem::getTaskId).collect(Collectors.toList());
// Group collection elements by an attribute (key: attribute value, value: sub-list)
Map<String, List<UserProfile>> userOrgGroups =
userProfiles.stream().collect(Collectors.groupingBy(UserProfile::getOrgId));
// Group and map to single element per key (handle duplicates by taking later value)
Map<String, Product> productMap =
products.stream().collect(Collectors.toMap(Product::getSku, Function.identity(), (oldVal, newVal) -> newVal));
// Filter elements matching a condition (score ≥ 85)
List<UserProfile> topUsers =
userProfiles.stream().filter(user -> user.getScore() >= 85).collect(Collectors.toList());
// Find the element with the maximum attribute value
Optional<UserProfile> maxScoreUser =
userProfiles.stream().max(Comparator.comparing(UserProfile::getScore));
UserProfile topUser = maxScoreUser.orElseThrow(NoSuchElementException::new);
// Check if any element has status not 1 or 2
boolean hasInvalidStatus = taskList.stream().anyMatch(task -> task.getStatusId() != 1 && task.getStatusId() != 2);
// Check if all elements have status 3
boolean allCompleted = taskList.stream().allMatch(task -> task.getStatusId() == 3);
// Multi-attribute sorting (ascending: result code → template ID → create time)
List<AuditLog> sortedLogs =
auditLogs.stream()
.sorted(Comparator.comparing(AuditLog::getResultCode)
.thenComparing(AuditLog::getTemplateId)
.thenComparing(AuditLog::getCreateTime))
.collect(Collectors.toList());
// Manual multi-attribute sort using Collections.sort
Collections.sort(auditLogs, new Comparator<AuditLog>() {
@Override
public int compare(AuditLog log1, AuditLog log2) {
long code1 = Long.parseLong(log1.getResultCode());
long code2 = Long.parseLong(log2.getResultCode());
int templateId1 = log1.getTemplateId();
int templateId2 = log2.getTemplateId();
Date time1 = log1.getCreateTime();
Date time2 = log2.getCreateTime();
if (code1 != code2) return code1 > code2 ? 1 : -1;
if (templateId1 != templateId2) return templateId1 > templateId2 ? 1 : -1;
return time1.after(time2) ? 1 : time1.before(time2) ? -1 : 0;
}
});
// Deduplicate string list and join with comma
String mergedTime = timeSlots.stream().distinct().collect(Collectors.joining(","));
// Split comma-separated string to long list
String idString = "101,102,103,104";
List<Long> idList = Arrays.stream(idString.split(",")).map(Long::parseLong).collect(Collectors.toList());
// Convert stream to array
Integer[] intArray = Stream.of(10, 20, 30).toArray(Integer[]::new);
// Zip two lists and update properties (same length)
List<Product> updatedProducts = IntStream.range(0, sourceProducts.size())
.mapToObj(i -> {
Product source = sourceProducts.get(i);
Product target = targetProducts.get(i);
source.setCategoryId(target.getCategoryId());
return source;
}).collect(Collectors.toList());
JPA Relationship Configuration
@ManyToOne / @OneToMany Scenario (Dpeartment ↔ Employees)
- Tables:
departments(id, name) andemployees(id, name, department_id)
Department PO Class:
@Entity
@Table(name = "departments")
@ApiModel(value = "Department")
public class DepartmentPO {
@Id
private String id;
@Column(name = "name")
private String departmentName;
@OneToMany(targetEntity = EmployeePO.class, cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private List<EmployeePO> employees;
}
Employee PO Class:
@Entity
@Table(name = "employees")
@ApiModel(value = "Employee")
public class EmployeePO {
@Id
private String id;
@Column(name = "name")
private String employeeName;
@ManyToOne(targetEntity = DepartmentPO.class, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private DepartmentPO department;
}
Employee Repository:
public interface EmployeeRepository extends JpaRepository<EmployeePO, String>, JpaSpecificationExecutor<EmployeePO> {
List<EmployeePO> findByDepartment(DepartmentPO department);
}
Usage Example:
DepartmentPO dept = new DepartmentPO();
dept.setId("dept-001");
List<EmployeePO> deptEmployees = employeeRepository.findByDepartment(dept);
Development Issues and Solutions
1. Date Field Serialization Format
Add @JsonFormat to specify serializasion/deserialization format for Date properties.
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private Date createdAt;
2. Vue Form Enter Key Triggers Page Refresh
Add @submit.native.prevent to the <el-form> tag to prevent default single-field form submission.
<el-form ref="queryForm" :model="queryParams" :inline="true" @submit.native.prevent="handleQuery">
<el-form-item label="Keyword">
<el-input v-model="queryParams.keyword" placeholder="Enter keyword" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">Search</el-button>
</el-form-item>
</el-form>
3. SQL Injection from Fuzzy Search Parameters
Escape SQL wildcards (_ and %) before constructing the LIKE clause.
String searchName = rawName.replaceAll("_", "/_").replaceAll("%", "/%");
cb.like(root.get("employeeName").as(String.class), "%" + searchName + "%");
4. Global Exception Handling
Use @RestControllerAdvice and @ExceptionHandler to centralize error handling.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
log.error("Uncaught exception: {}", e.getMessage());
if (e instanceof BindException) {
String errorMsg = ((BindException) e).getAllErrors().get(0).getDefaultMessage();
return ResponseEntity.badRequest().body(new ErrorResponse("400", errorMsg));
} else if (e instanceof MethodArgumentTypeMismatchException) {
return ResponseEntity.badRequest().body(new ErrorResponse("400", "Invalid parameter type"));
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("500", "Internal server error"));
}
}
5. Vue Page Cache Control
Add noCache: true to the route meta to disable caching when navigating away.
const routes = [
{
path: '/orders',
component: OrdersPage,
name: 'Orders',
meta: {
title: 'Orders List',
noCache: true
}
}
];