Java 设置<;字符串>;将[1.0,1]视为不同的值

Java 设置<;字符串>;将[1.0,1]视为不同的值,java,set,Java,Set,我有一个这样的代码序列,这是数据挖掘算法准确性检查的一部分 ie将经过训练的数据与我的算法中的一些预测值进行比较,并通过比较两个类标签进行准确性检查 假设我的值是[No,No],[No,Yes],[1.0,1],[1,1],[1,0],它们是类标签 我试图比较我预测数据的准确性 public void reduce(Text key, Iterable<Text> values, Context context) Set<String> set = new Has

我有一个这样的代码序列,这是数据挖掘算法准确性检查的一部分

ie将经过训练的数据与我的算法中的一些预测值进行比较,并通过比较两个类标签进行准确性检查

假设我的值是
[No,No],[No,Yes],[1.0,1],[1,1],[1,0]
,它们是类标签 我试图比较我预测数据的准确性

public void reduce(Text key, Iterable<Text> values, Context context)
    Set<String> set = new HashSet<String>();
    for (Text val : values) {
        set.add(val.toString());
    }
    int count = set.size();
    if(count == 1){
        System.out.println("Correct class label");
        corClass++;
    }
    else{
        System.out.println("InCorrect class label");
    }
对我来说,[1.0,1]这属于不正确的类别标签

Set
Set将[1.0,1]视为不同的事件,尽管它们是相等的,但却是双精度和整数

如何修复解决方案

请建议


提前谢谢

您似乎有代码不遵守的规则。你说
1.0
是“双精度”。是否有规则确定在何种条件下代码是双精度的?例如,“1e10”是双精度--1 x 10^10吗?还是像“是”这样的字符串


1.0
1
是不同的字符串。如果你有一些比较规则,使这两件事完全相同,你必须在某处实现它——它不会神奇地发生。你的问题并不清楚规则到底是什么,但不管它是什么,都要实现它。

目前,你正在使用一组字符串来存储数据。因为它是一组字符串,所以该集合将允许任何不相等字符串的元素。如果您正在编写一个不同的应用程序,您真的需要字符串相等,如果
“1”.equals(“1.000”)==true
,这难道不会令人困惑吗

在这种情况下,我认为最好不要使用集合

对于任何基于数字或字符串的等式,此函数都应正常工作:

public boolean stringOrDoubleEqual(String a,String b){
    try{
       //Change the 0.001 to the acceptable error for your application.
       return Math.abs(Double.parseDouble(a)-Double.parseDouble(b))<0.001;
    }catch(NumberFormatException e){
       return a.equals(b);
    }
}
public boolean stringOrDoubleEqual(字符串a、字符串b){
试一试{
//将0.001更改为应用程序的可接受错误。

return Math.abs(Double.parseDouble(a)-Double.parseDouble(b))你不是在存储一组严格意义上的字符串,而是在存储一组字符串和整数。你不知道下一步要放哪一个,但你不一定关心这一点;你只是在为你的用例利用集合属性

您可以做什么,而不只是创建一个集合来存储其中的大多数对象

Set<?> set = new HashSet<>();
for (Text val : values) {
    try {
        set.add(Double.valueOf(val.toString()).intValue());
    } catch (NumberFormatException nfe) {
        set.add(val.toString());
    }
}
Set Set=newhashset();
用于(文本值:值){
试一试{
set.add(Double.valueOf(val.toString()).intValue());
}捕获(NumberFormatException nfe){
set.add(val.toString());
}
}

当我们谈论使用异常作为控制流时,这不是一件很吸引人的事情,但这会让你克服眼前的痛苦。

可能是因为
“1.0”!=“1”
?听起来你想在调用
toString()之前将所有数字转换成整数
Set
意味着集合的值是一个
String
。字符串
1.0
不等于字符串
1
@Jon:是的,但我怀疑它本身是字符串格式的输入值。值是Text~String为什么说
1.0
是双精度的?你有什么规则来限制这种类型吗可以保存吗?如果可以,实现此规则的代码在哪里?@SreeVeni-集合可以保存哪种类型的值?。如果必须比较程序中的某个地方的
1.5
1.1
,则将所有值转换为整数是没有意义的。不要依赖等于来表示基本的双精度。永远。
parseDouble
会给您提供ba勾选一个基元双精度。即使您使用的是
double
,也不要这样做;
equals
在两种特殊情况下有一个非常相似的假设。@Makoto如果您仔细观察,您会发现parse double生成的双精度与==进行比较,然后返回。使用
equals
的唯一情况是解析失败。然后我们将字符串a和b与
.equals
进行比较。是的。我可以看到您正在将原始双精度与
=
@Makoto进行比较。哦,我明白了。我以为您的意思是字面上的
等于
。我可能应该在回击您之前检查一下您的代表。如果您想建议编辑,请随意:)这样您就不会输了e类型集的安全性?到目前为止,这仍然是最好的答案,但有点困扰我。基本上,其中的所有内容都被视为
对象
,但集的重复数据消除属性被保留。如果您不想从集中获得任何内容,这很好。如果您这样做,您将需要查看自定义类型。Yep、 没错。OP的更多细节在这里会很有帮助。
Set<?> set = new HashSet<>();
for (Text val : values) {
    try {
        set.add(Double.valueOf(val.toString()).intValue());
    } catch (NumberFormatException nfe) {
        set.add(val.toString());
    }
}