如何用java.util.Scanner实现带建议列表的自动补全功能
实现实时地名自动补全的方案
嘿,早上好!这个需求完全能实现,不过得先提个醒:你现在用的java.util.Scanner是控制台里的阻塞式输入工具——它得等用户敲完回车才会返回输入内容,根本做不到实时监听每一个字符的输入变化。所以要实现「输入到3个字母就实时弹匹配结果」的效果,咱们得换个思路,下面给你两种可行的方案:
方案一:GUI程序(推荐,原生支持实时监听)
如果你的系统是带界面的,用Swing或者JavaFX的文本组件就能轻松搞定,它们原生支持监听文本输入的每一次变化。这里用Swing举个完整的例子:
import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.*; import java.util.List; import java.util.stream.Collectors; public class PlaceAutocompleteGUI { // 替换成你的40个地名列表 private static final List<String> PLACES = List.of( "Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Chengdu", "Chongqing", "Wuhan", "Hangzhou", "Xiamen", "Qingdao" ); public static void main(String[] args) { JFrame frame = new JFrame("地名自动补全"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 300); frame.setLayout(new BorderLayout()); // 输入框 JTextField inputField = new JTextField(); frame.add(inputField, BorderLayout.NORTH); // 展示匹配结果的列表 JList<String> resultList = new JList<>(); frame.add(new JScrollPane(resultList), BorderLayout.CENTER); // 给输入框添加文档监听器,监听每一次文本变化 inputField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { updateMatches(); } @Override public void removeUpdate(DocumentEvent e) { updateMatches(); } @Override public void changedUpdate(DocumentEvent e) { updateMatches(); } // 核心逻辑:过滤匹配的地名并展示 private void updateMatches() { String userInput = inputField.getText().trim(); if (userInput.length() >= 3) { // 过滤前缀匹配的地名(要忽略大小写的话,两边都转成toLowerCase()即可) List<String> matches = PLACES.stream() .filter(place -> place.startsWith(userInput)) .collect(Collectors.toList()); resultList.setListData(matches.toArray(new String[0])); } else { // 输入不足3个字符,清空结果 resultList.setListData(new String[0]); } } }); frame.setVisible(true); } }
这个例子的逻辑很清晰:
- 用
JTextField接收用户输入 - 通过
DocumentListener监听文本的插入、删除操作 - 每次输入变化时,检查输入长度是否≥3,是就过滤地名列表,把匹配结果放到
JList里展示 - 用户输入4、5个字母时,过滤逻辑会自动匹配更长的前缀,完全符合你的需求
方案二:控制台程序(需依赖第三方库)
如果一定要在纯控制台环境下实现,原生JDK的Scanner做不到实时监听,得用第三方库比如JLine(它是Maven、Gradle等工具的控制台底层依赖)。
首先需要引入JLine的依赖(以Maven为例):
<dependency> <groupId>org.jline</groupId> <artifactId>jline</artifactId> <version>3.24.1</version> </dependency>
然后可以这样实现自动补全:
import org.jline.reader.*; import org.jline.reader.impl.completer.StringsCompleter; import org.jline.terminal.Terminal; import org.jline.terminal.TerminalBuilder; import java.io.IOException; import java.util.List; public class ConsolePlaceAutocomplete { private static final List<String> PLACES = List.of( "Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Chengdu", "Chongqing", "Wuhan", "Hangzhou", "Xiamen", "Qingdao" ); public static void main(String[] args) throws IOException { Terminal terminal = TerminalBuilder.terminal(); LineReader reader = LineReaderBuilder.builder() .terminal(terminal) // 传入地名列表作为补全候选 .completer(new StringsCompleter(PLACES)) .build(); terminal.writer().println("请输入地名(输入前缀后按Tab键自动补全):"); terminal.flush(); while (true) { try { String input = reader.readLine("> "); terminal.writer().println("你最终输入的地名:" + input); terminal.flush(); } catch (UserInterruptException | EndOfFileException e) { // 用户按Ctrl+C或Ctrl+D退出 break; } } terminal.close(); } }
这个方案里,JLine会自动监听用户输入的前缀,当输入≥3个字母且匹配地名时,按下Tab键就能选择对应的补全项,也能满足你的核心需求。
内容的提问来源于stack exchange,提问作者Royce
相关产品推荐
相关产品推荐

