java - 流的奇怪错误
问题描述
所以我创建了自己的 Set,它只是一个常规的集合,但有额外的功能(例如我的集合只存储绝对值)。
这是我的代码:
import java.util.*;
public class SortedByAbsoluteValueIntegerSet<E> extends HashSet<E> {
private Set<Integer> mySet;
public SortedByAbsoluteValueIntegerSet() {
mySet = new HashSet<Integer>();
}
@Override
public int size() {
return mySet.size();
}
@Override
public boolean add(E e){
return mySet.add(Math.abs((Integer) e));
}
@Override
public boolean remove(Object o) {
return mySet.remove(o);
}
@Override
public boolean contains(Object o){
return mySet.contains(o);
}
@Override
public boolean addAll(Collection<? extends E> c) {
List<Integer> myList = new ArrayList<>();
for (Object e: c) {
myList.add(Math.abs((Integer) e));
}
return mySet.addAll(myList);
}
@Override
public String toString(){
return mySet.toString();
}
}
我在 JUnit 中有一个测试用例,但失败了。因为我的代码有问题。出于演示目的,为了更好地解释我的问题,我创建了两个函数,它们很好地显示了问题。
这是问题所在:
public static void testSortedByAbsoluteValueIntegerSet() {
Set<Integer> set1 = new SortedByAbsoluteValueIntegerSet();
Set<Integer> set2 = new HashSet<>();
set1.add(5);
set1.add(3);
set2.add(5);
set2.add(3);
String x = toString(set1); //x is ""
String t = toString(set2); //t is "3 5"
}
public static String toString(final Collection<Integer> collection) {
return String.join(" ", collection.stream()
.map(i -> Integer.toString(i))
.toArray(String[]::new));
}
所以问题出现在这一行:
String x = toString(set1); //x is always an empty string
String t = toString(set2); //t works correctly
当我通过调试器时,我看到 String x 始终是一个空字符串,而 String t 可以正常工作。顺便说一句,set1 是我创建的集合的表示,而 set2 只是一个常规的哈希集。
问题是:我怎样才能修复我的 SortedByAbsoluteValueIntegerSet 类,以便 toString() 方法也适用于我自己创建的集合。
PS我是新来的流,我真的不明白这个问题,为什么会发生。
解决方案
这是因为您正在扩展 HashSet,但也使用了内部 Set。
添加时,您将添加到内部 Set 但使用 collection.stream() 时,它会调用继承的 HashSet (为空)。
我相信对你来说最简单的方法是删除内部的“mySet”并在覆盖的方法中调用继承的方法。
例如,您的 add 方法将是
@Override
public boolean add(E e){
return super.add(Math.abs((Integer) e));
}
(然后您不需要覆盖 toString 或拆分器的大小、删除、包含)
完整示例:
import java.util.*;
public class SortedByAbsoluteValueIntegerSet extends HashSet<Integer> {
@Override
public boolean add(Integer e){
return super.add(Math.abs(e));
}
@Override
public boolean addAll(Collection<? extends Integer> c) {
List<Integer> myList = new ArrayList<>();
for (Integer e: c) {
myList.add(Math.abs(e));
}
return super.addAll(myList);
}
}
推荐阅读
- gcloud - 如何通过 gcloud cli args 或环境变量将 secretEnv 指定给 cloudbuild.yaml
- bluetooth - 蓝牙 LE 传感器与笔记本电脑 BLE,信号强度的差异?
- windows - 如何从 Windows 内核模式驱动程序代码中获取当前工作目录?
- c++ - 将 ' :: ' 替换为 ' 。' 在 C++ 中产生歧义?
- stata - 基于二元选择设置每组内变量的值
- rust - Rust - 混合默认宏和个人默认实现
- javascript - 不明白如何在工具提示中显示提示
- android - 请问我将如何使用 Retrofit 参数化这个端点?
- android - 如何使用gson解析通过retrofit2从json数组中检索特定数据
- javascript - 如何停止在 HTML 中显示重复的 JSON 数据?