Java实现同键值分组存储及含ABC序列用户查询
问题与实现修正
需求说明
给定原始键值对数据:
bob:V bob:A bob:B bob:C bob:C sally:B sally:C sally:A steve:A steve:B steve:C
需要完成两项任务:
- 将数据整理为指定格式输出:
bob={V,A,B,C,C}, sally={B,C,A}, steve={A,B,C} - 筛选出事件序列中包含连续
ABC的用户姓名(预期结果:bob、steve)
原始代码问题分析
你提供的代码思路正确,但存在几个小问题:
- 使用
String::concat拼接字符虽然能实现序列判断,但不利于后续生成{X,X,X}格式的输出; - 定义了
BiPredicate但未实际使用,属于冗余代码; - 代码中
System.out.println的字符串换行写法会导致编译错误。
修正后的完整实现
import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Solution { public static void main(String[] args) { List<LogItem> exampleInputItems = new ArrayList<>(); exampleInputItems.add(new LogItem("bob", 'V')); exampleInputItems.add(new LogItem("bob", 'A')); exampleInputItems.add(new LogItem("steve", 'A')); exampleInputItems.add(new LogItem("bob", 'B')); exampleInputItems.add(new LogItem("bob", 'C')); exampleInputItems.add(new LogItem("bob", 'C')); exampleInputItems.add(new LogItem("steve", 'B')); exampleInputItems.add(new LogItem("sally", 'B')); exampleInputItems.add(new LogItem("steve", 'C')); exampleInputItems.add(new LogItem("sally", 'C')); exampleInputItems.add(new LogItem("sally", 'A')); // 完成格式输出和筛选任务 Map<String, List<Character>> userEventMap = convertToUserEventMap(exampleInputItems); printFormattedData(userEventMap); List<String> targetUsers = findUsersWithSequence(userEventMap, "ABC"); // 验证结果 if (targetUsers.size() != 2) { throw new RuntimeException("Wrong number of names found. Found: " + targetUsers); } if (!targetUsers.contains("bob")) { throw new RuntimeException("Did not find \"bob\" in the returnedNames: " + targetUsers); } if (!targetUsers.contains("steve")) { throw new RuntimeException("Did not find \"steve\" in the returnedNames: " + targetUsers); } System.out.println("The example passed."); } /** * 将LogItem列表转换为<用户名, 事件字符列表>的Map */ private static Map<String, List<Character>> convertToUserEventMap(List<LogItem> eventsInput) { return eventsInput.stream() .collect(Collectors.groupingBy( LogItem::getUserId, Collectors.mapping(LogItem::getEventChar, Collectors.toList()) )); } /** * 按照指定格式输出用户事件数据 */ private static void printFormattedData(Map<String, List<Character>> userEventMap) { String formatted = userEventMap.entrySet().stream() .map(entry -> { String events = entry.getValue().stream() .map(String::valueOf) .collect(Collectors.joining(",")); return entry.getKey() + "={" + events + "}"; }) .collect(Collectors.joining(", ")); System.out.println(formatted); } /** * 筛选出事件序列包含指定连续字符串的用户 */ private static List<String> findUsersWithSequence(Map<String, List<Character>> userEventMap, String targetSequence) { return userEventMap.entrySet().stream() .filter(entry -> { String eventStr = entry.getValue().stream() .map(String::valueOf) .collect(Collectors.joining()); return eventStr.contains(targetSequence); }) .map(Map.Entry::getKey) .collect(Collectors.toList()); } static class LogItem { private String userId; private char eventChar; private LocalDateTime dateTime; LogItem(String userId, char eventChar) { this.userId = userId; this.eventChar = eventChar; this.dateTime = LocalDateTime.now(); } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public char getEventChar() { return eventChar; } public void setEventChar(char eventChar) { this.eventChar = eventChar; } public LocalDateTime getDateTime() { return dateTime; } public void setDateTime(LocalDateTime dateTime) { this.dateTime = dateTime; } } }
代码说明
- 数据转换:使用
Collectors.groupingBy+Collectors.mapping将数据整理为<用户名, 事件字符列表>的Map,既保留了事件顺序,也方便后续格式处理和序列判断。 - 格式输出:遍历Map,将每个用户的字符列表用逗号拼接,再包裹成
{X,X,X}格式,最后把所有用户的结果用逗号分隔输出。 - 序列筛选:将每个用户的字符列表拼接成字符串,直接判断是否包含目标连续序列
ABC,符合条件的用户姓名收集为结果列表。
运行代码后,会先输出指定格式的字符串,再完成验证并打印The example passed.。
内容的提问来源于stack exchange,提问作者NewBond007
相关产品推荐
相关产品推荐

