本文目录导读:

我来帮你理解 JEditorPane、HTMLEditorKit、Parser 以及 Set 集合之间的关系和处理方式。
核心关系图
JEditorPane (文本编辑器组件)
↓ 使用
HTMLEditorKit (HTML编辑器工具包)
↓ 包含
Parser (HTML解析器)
↓ 处理
Set<Element> (集合存储解析结果)
基础使用示例
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import java.util.*;
public class HTMLParserExample {
public static void main(String[] args) {
// 创建 JEditorPane
JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");
// 设置 HTML 内容
String html = "<html><body><h1>标题</h1><p>段落内容</p></body></html>";
editorPane.setText(html);
// 获取编辑器工具包
HTMLEditorKit kit = (HTMLEditorKit) editorPane.getEditorKit();
// 使用 Set 存储唯一元素
Set<Element> elementSet = new HashSet<>();
analyzeHTMLElements(editorPane.getDocument(), elementSet);
System.out.println("唯一元素数量: " + elementSet.size());
}
private static void analyzeHTMLElements(Document doc, Set<Element> elements) {
Element root = doc.getDefaultRootElement();
traverseElements(root, elements);
}
private static void traverseElements(Element element, Set<Element> elementSet) {
// 添加到 Set 去重
elementSet.add(element);
// 遍历子元素
for (int i = 0; i < element.getElementCount(); i++) {
traverseElements(element.getElement(i), elementSet);
}
}
}
完整解析器与集合处理
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;
import javax.swing.text.*;
import java.util.*;
public class AdvancedHTMLParsing {
public static class HTMLElementData {
private String tagName;
private String textContent;
private Map<String, String> attributes;
public HTMLElementData(String tagName, String textContent) {
this.tagName = tagName;
this.textContent = textContent;
this.attributes = new HashMap<>();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HTMLElementData that = (HTMLElementData) o;
return Objects.equals(tagName, that.tagName) &&
Objects.equals(textContent, that.textContent);
}
@Override
public int hashCode() {
return Objects.hash(tagName, textContent);
}
@Override
public String toString() {
return "Tag: " + tagName + ", Content: " + textContent;
}
}
public static class HTMLParserManager {
private JEditorPane editorPane;
private HTMLEditorKit editorKit;
private Set<HTMLElementData> uniqueElements;
public HTMLParserManager() {
editorPane = new JEditorPane();
editorPane.setContentType("text/html");
editorKit = (HTMLEditorKit) editorPane.getEditorKit();
uniqueElements = new TreeSet<>((e1, e2) -> {
int tagCompare = e1.tagName.compareTo(e2.tagName);
return tagCompare != 0 ? tagCompare :
e1.textContent.compareTo(e2.textContent);
});
}
public void parseHTML(String html) {
editorPane.setText(html);
try {
// 获取文档
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
// 使用 Set 集合处理元素
extractElements(doc.getDefaultRootElement());
System.out.println("解析完成,唯一元素数: " + uniqueElements.size());
printUniqueElements();
} catch (Exception e) {
e.printStackTrace();
}
}
private void extractElements(Element element) {
// 获取元素属性
AttributeSet attrs = element.getAttributes();
String tagName = element.getName();
// 创建并添加到 Set
try {
int start = element.getStartOffset();
int end = element.getEndOffset();
String text = element.getDocument().getText(start, end - start);
HTMLElementData data = new HTMLElementData(tagName, text.trim());
uniqueElements.add(data);
} catch (BadLocationException e) {
e.printStackTrace();
}
// 递归处理子元素
for (int i = 0; i < element.getElementCount(); i++) {
extractElements(element.getElement(i));
}
}
public void printUniqueElements() {
System.out.println("=== 唯一元素列表 ===");
uniqueElements.forEach(System.out::println);
}
// 集合操作
public Set<String> getUniqueTagNames() {
Set<String> tagNames = new HashSet<>();
uniqueElements.forEach(e -> tagNames.add(e.tagName));
return tagNames;
}
public Map<String, Set<String>> groupByTagName() {
Map<String, Set<String>> grouped = new HashMap<>();
uniqueElements.forEach(element -> {
grouped.computeIfAbsent(element.tagName, k -> new LinkedHashSet<>())
.add(element.textContent);
});
return grouped;
}
}
public static void main(String[] args) {
HTMLParserManager parser = new HTMLParserManager();
String complexHTML = """
<html>
<head><title>测试页面</title></head>
<body>
<h1>主标题</h1>
<div class="content">
<p>第一段内容</p>
<p>第二段内容</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
<li>列表项1</li> <!-- 重复内容 -->
</ul>
<a href="http://example.com">链接</a>
</div>
</body>
</html>
""";
parser.parseHTML(complexHTML);
// 使用集合方法
System.out.println("\n=== 唯一标签名称 ===");
parser.getUniqueTagNames().forEach(System.out::println);
System.out.println("\n=== 按标签分组 ===");
parser.groupByTagName().forEach((tag, contents) -> {
System.out.println(tag + ": " + contents);
});
}
}
自定义解析器与集合处理
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.*;
import java.util.*;
import java.util.stream.*;
public class CustomHTMLParser {
// 使用 HashSet 进行元素去重
public static Set<HTML.Tag> extractUniqueTags(HTMLDocument doc) {
Set<HTML.Tag> uniqueTags = new HashSet<>();
ElementIterator it = new ElementIterator(doc);
Element element;
while ((element = it.next()) != null) {
AttributeSet attrs = element.getAttributes();
Object tagObject = attrs.getAttribute(StyleConstants.NameAttribute);
if (tagObject instanceof HTML.Tag) {
uniqueTags.add((HTML.Tag) tagObject);
}
}
return uniqueTags;
}
// 使用 TreeSet 进行排序和去重
public static Set<String> extractSortedTextContents(HTMLDocument doc) {
Set<String> contents = new TreeSet<>();
ElementIterator it = new ElementIterator(doc);
Element element;
while ((element = it.next()) != null) {
try {
String text = doc.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
if (!text.trim().isEmpty()) {
contents.add(text.trim());
}
} catch (BadLocationException e) {
e.printStackTrace();
}
}
return contents;
}
// 使用 EnumSet 处理特定标签
public enum HTMLTagType {
HEADING, PARAGRAPH, LINK, LIST, IMAGE, OTHER
}
public static Map<HTMLTagType, Set<Element>> categorizeElements(HTMLDocument doc) {
Map<HTMLTagType, Set<Element>> categorized = new HashMap<>();
EnumSet<HTMLTagType> allTypes = EnumSet.allOf(HTMLTagType.class);
allTypes.forEach(type -> categorized.put(type, new LinkedHashSet<>()));
ElementIterator it = new ElementIterator(doc);
Element element;
while ((element = it.next()) != null) {
AttributeSet attrs = element.getAttributes();
Object tagObject = attrs.getAttribute(StyleConstants.NameAttribute);
if (tagObject instanceof HTML.Tag) {
HTML.Tag tag = (HTML.Tag) tagObject;
HTMLTagType type = determineTagType(tag);
categorized.get(type).add(element);
}
}
return categorized;
}
private static HTMLTagType determineTagType(HTML.Tag tag) {
if (tag == HTML.Tag.H1 || tag == HTML.Tag.H2 ||
tag == HTML.Tag.H3 || tag == HTML.Tag.H4) {
return HTMLTagType.HEADING;
} else if (tag == HTML.Tag.P) {
return HTMLTagType.PARAGRAPH;
} else if (tag == HTML.Tag.A) {
return HTMLTagType.LINK;
} else if (tag == HTML.Tag.UL || tag == HTML.Tag.OL || tag == HTML.Tag.LI) {
return HTMLTagType.LIST;
} else if (tag == HTML.Tag.IMG) {
return HTMLTagType.IMAGE;
}
return HTMLTagType.OTHER;
}
public static void main(String[] args) {
JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");
String html = "<html><body><h1>Title</h1><p>Paragraph</p><a href='#'>Link</a></body></html>";
editorPane.setText(html);
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
// 使用各种集合处理
Set<HTML.Tag> uniqueTags = extractUniqueTags(doc);
Set<String> sortedContents = extractSortedTextContents(doc);
Map<HTMLTagType, Set<Element>> categorized = categorizeElements(doc);
System.out.println("唯一标签: " + uniqueTags);
System.out.println("排序内容: " + sortedContents);
System.out.println("分类元素: " + categorized.keySet());
}
}
集合操作最佳实践
public class HTMLCollectionBestPractices {
// 多线程安全的集合处理
public static class ThreadSafeHTMLCollection {
private final Set<String> processedElements =
Collections.synchronizedSet(new HashSet<>());
private final Set<String> threadSafeSet = new ConcurrentHashMap<>()
.newKeySet();
public void processDocument(HTMLDocument doc) {
ElementIterator it = new ElementIterator(doc);
Element element;
while ((element = it.next()) != null) {
String elementId = element.getName() + ":" +
element.getStartOffset();
// 线程安全的添加操作
synchronized(processedElements) {
if (processedElements.add(elementId)) {
// 处理新元素
processElement(element);
}
}
}
}
private void processElement(Element element) {
// 元素处理逻辑
}
}
// 性能优化的集合操作
public static class OptimizedHTMLCollection {
private final Set<String> elementCache = new LinkedHashSet<>(1000);
private final Map<String, Integer> elementFrequency = new HashMap<>();
public void analyzeHTMLStructure(HTMLDocument doc) {
ElementIterator it = new ElementIterator(doc);
Element element;
while ((element = it.next()) != null) {
String path = buildElementPath(element);
// 使用计算频率的集合操作
elementFrequency.merge(path, 1, Integer::sum);
elementCache.add(path);
}
// 过滤高频元素
Set<String> frequentElements = elementFrequency.entrySet()
.stream()
.filter(entry -> entry.getValue() > 1)
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
private String buildElementPath(Element element) {
StringBuilder path = new StringBuilder();
Element parent = element.getParentElement();
while (parent != null) {
path.insert(0, "/" + parent.getName());
parent = parent.getParentElement();
}
path.append("/").append(element.getName());
return path.toString();
}
}
}
- JEditorPane - 显示和编辑 HTML 内容的 Swing 组件
- HTMLEditorKit - 提供 HTML 文档的创建和操作能力
- Parser - 内部使用
HTMLDocument和ElementIterator进行解析 - Set 集合 -
HashSet- 快速去重LinkedHashSet- 保持插入顺序的去重TreeSet- 排序后的元素集合EnumSet- 枚举类型的高效集合
这样可以高效地处理 HTML 元素,利用集合的各种特性来实现去重、排序、分组等操作。