Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Java Development Tips and Examples

Tech May 8 5

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) and employees (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
    }
  }
];

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.