Fundamentals 22 min read

Java Programming Techniques: Collections, ThreadLocal, Pair, Enum, Union, and Generics

The article presents a toolbox of practical Java techniques—including using HashSet for fast duplicate detection, HashMap for building hierarchical structures, ThreadLocal for thread‑specific data, Pair and custom holder classes for multiple return values, enum definitions, union‑style classes, and generic and wildcard patterns—to streamline everyday coding tasks.

Amap Tech
Amap Tech
Amap Tech
Java Programming Techniques: Collections, ThreadLocal, Pair, Enum, Union, and Generics

This article shares a collection of practical Java programming techniques gathered from extensive coding experience, covering data structures, utility classes, and generic programming.

Using HashSet to check primary key existence – HashSet implements Set via a hash table, offering O(1) average lookup when there are no hash collisions. The article provides a method to find the first repeated character in a string using a HashSet and shows a simplified version that relies on the add method’s boolean return value.

/** Find first repeated character */
public static char findFirstRepeatedChar(String string) {
    if (Objects.isNull(string) || string.isEmpty()) {
        return null;
    }
    char[] charArray = string.toCharArray();
    Set<Character> charSet = new HashSet<>(charArray.length);
    for (char ch : charArray) {
        if (charSet.contains(ch)) {
            return ch;
        }
        charSet.add(ch);
    }
    return null;
}

// Simplified version
if (!charSet.add(ch)) {
    return ch;
}

Using HashMap for key‑value mapping – The article explains that HashMap consists of an array and linked lists to resolve collisions, with O(1) average performance. An example builds a menu tree from a flat list of menu records.

/** Build menu tree */
public static List<MenuVO> buildMenuTree(List<MenuDO> menuList) {
    if (CollectionUtils.isEmpty(menuList)) {
        return Collections.emptyList();
    }
    Map<Long, MenuVO> menuMap = new HashMap<>(menuList.size());
    List<MenuVO> rootList = new ArrayList<>();
    for (MenuDO menuDO : menuList) {
        Long menuId = menuDO.getId();
        MenuVO menu = menuMap.get(menuId);
        if (menu == null) {
            menu = new MenuVO();
            menu.setChildList(new ArrayList<>());
            menuMap.put(menuId, menu);
        }
        menu.setId(menuDO.getId());
        menu.setName(menuDO.getName());
        menu.setUrl(menuDO.getUrl());
        Long parentId = menuDO.getParentId();
        if (Objects.nonNull(parentId)) {
            MenuVO parentMenu = menuMap.get(parentId);
            if (parentMenu == null) {
                parentMenu = new MenuVO();
                parentMenu.setId(parentId);
                parentMenu.setChildList(new ArrayList<>());
                menuMap.put(parentId, parentMenu);
            }
            parentMenu.getChildList().add(menu);
        } else {
            rootList.add(menu);
        }
    }
    return rootList;
}

ThreadLocal for thread‑specific objects – Demonstrates how ThreadLocal can store per‑thread data such as pagination parameters or date formatters, avoiding thread‑safety issues of SimpleDateFormat. The article also warns about potential memory leaks and recommends calling remove() when done.

/** Local date format */
private static final ThreadLocal<DateFormat> LOCAL_DATE_FORMAT = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd");
    }
};

public static String formatDate(Date date) {
    return LOCAL_DATE_FORMAT.get().format(date);
}

Pair class for returning two results – Shows how to encapsulate a point and its distance using a custom PointAndDistance class and also using Apache Commons Pair. Example code illustrates both approaches.

/** Point and distance class */
public static class PointAndDistance {
    private Point point;
    private Double distance;
    // getters, setters, constructors omitted for brevity
}

public static PointAndDistance getNearestPointAndDistance(Point point, Point[] points) {
    // implementation omitted
}

// Using Pair
public static Pair<Point, Double> getNearestPointAndDistance(Point point, Point[] points) {
    // implementation omitted
    return Pair.of(nearestPoint, nearestDistance);
}

Enum definitions – Provides two ways to define enums in Java: a pre‑JDK5 class‑based simulation and the modern enum keyword, with methods to retrieve value and description.

/** Enum using class */
public final class OrderStatus {
    private final int value;
    private final String description;
    public static final OrderStatus CREATED = new OrderStatus(1, "已创建");
    // other constants omitted
    private OrderStatus(int value, String description) { ... }
    public int getValue() { return value; }
    public String getDescription() { return description; }
}

/** Enum using keyword */
public enum OrderStatus {
    CREATED(1, "已创建"),
    PROCESSING(2, "进行中"),
    FINISHED(3, "已完成");
    private final int value;
    private final String description;
    private OrderStatus(int value, String description) { ... }
    public int getValue() { return value; }
    public String getDescription() { return description; }
}

Holder classes for output parameters – Introduces a simple LongHolder to emulate out parameters in Java, with example usage in pagination handling.

public class LongHolder {
    private long value;
    public LongHolder() {}
    public LongHolder(long value) { this.value = value; }
    // getters and setters omitted
}

public void handleExpiredOrder() {
    LongHolder minIdHolder = new LongHolder(0L);
    for (int pageIndex = 0; pageIndex < PAGE_COUNT; pageIndex++) {
        if (!handleExpiredOrder(pageIndex, minIdHolder)) {
            break;
        }
    }
}

Union‑like class to simulate C/C++ unions – Shows a Java class that holds mutually exclusive fields (e.g., news content) and methods to set the message type, clearing previous content to mimic union behavior.

public class CustomerMessage {
    private String msgType;
    private String toUser;
    private News news; // mutually exclusive field
    public static final String MSG_TYPE_NEWS = "news";
    public void setMsgType(String msgType) {
        removeMsgContent();
        this.msgType = Objects.requireNonNull(msgType);
        if (MSG_TYPE_NEWS.equals(msgType)) {
            this.news = new News();
        } else {
            throw new IllegalArgumentException("Unsupported message type");
        }
    }
    private void removeMsgContent() {
        if (MSG_TYPE_NEWS.equals(this.msgType)) {
            this.news = null;
        }
        this.msgType = null;
    }
    // getters/setters omitted
}

Generics and wildcard usage – Defines a generic holder, a generic data provider interface, a shallow‑copy utility method, and demonstrates wildcard and bounded‑type usage (e.g., NumberHolder<T extends Number>).

public class GenericHolder<T> {
    private T value;
    public GenericHolder() {}
    public GenericHolder(T value) { this.value = value; }
    // getters/setters omitted
}

public interface DataProvider<T> {
    T getData();
}

public static <T> T shallowCopy(Object source, Class<T> clazz) throws BeansException {
    if (source == null) return null;
    try {
        T target = clazz.newInstance();
        BeanUtils.copyProperties(source, target);
        return target;
    } catch (Exception e) {
        throw new BeansException("Failed to instantiate class", e);
    }
}

public static <T extends Number> void printValue(GenericHolder<T> holder) {
    System.out.println(holder.getValue());
}

The article concludes with a brief author bio and references to related posts.

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.

JavaCollectionsThreadLocalEnums
Amap Tech
Written by

Amap Tech

Official Amap technology account showcasing all of Amap's technical innovations.

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.