使用Comparator在TreeMap中获取Null

时间:2017-09-23 13:27:28

标签: java treemap

我有一个名为Empl的类和两个名为MySalaryCompMyNameComp的比较器。

当我运行此代码时,我将null作为MySalaryComp中的值,如下面的输出所示。

public class Test{

    public static void main(String a[]) {
        TreeMap<Empl, String> tm = new TreeMap<Empl, String>(new MyNameComp());
        tm.put(new Empl("zzz", 3000), "RAM");
        tm.put(new Empl("aaa", 6000), "JOHN");
        Set<Empl> keys = tm.keySet();
        for (Empl key : keys) {
            System.out.println(key + " ==> " + tm.get(key));
        }

        TreeMap<Empl, String> trmap = new TreeMap<Empl, String>(new MySalaryComp());
        trmap.put(new Empl("zzz", 3000), "RAM");
        trmap.put(new Empl("aaa", 6000), "JOHN");
        Set<Empl> ks = trmap.keySet();
        for (Empl key : ks) {
            System.out.println(key + " ==> " + trmap.get(key));
        }
    }
}

class MyNameComp implements Comparator<Empl> {

    @Override
    public int compare(Empl e1, Empl e2) {
        return e1.getName().compareTo(e2.getName());
    }
}

class MySalaryComp implements Comparator<Empl> {

    @Override
    public int compare(Empl e1, Empl e2) {
        if (e1.getSalary() > e2.getSalary()) {
            return 1;
        } else {
            return -1;
        }
    }
}

class Empl {

    private String name;
    private int salary;

    public Empl(String n, int s) {
        this.name = n;
        this.salary = s;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }


}

上述代码的输出为:

Name: aaa-- Salary: 6000 ==> JOHN
Name: zzz-- Salary: 3000 ==> RAM
Name: zzz-- Salary: 3000 ==> null
Name: aaa-- Salary: 6000 ==> null

有人可以帮助我理解为什么会显示空值吗?以及如何解决它。

3 个答案:

答案 0 :(得分:2)

您的比较器未正确实施。 阅读JavaDocs:

https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

  

比较其订单的两个参数。返回一个负整数,   零或正整数,因为第一个参数小于,等于   到,或大于第二个。

试试这个:

@Override
public int compare(Employee e1, Employee e2) {
  return e1.getSalary() - e2.getSalary();
}

为什么需要返回0?
如果你看一下TreeMap的源代码,你会看到:

final Entry<K,V> getEntry(Object key) {
  // Offload comparator-based version for sake of performance
  if (comparator != null)
    return getEntryUsingComparator(key);
  if (key == null)
    throw new NullPointerException();
  @SuppressWarnings("unchecked")
  Comparable<? super K> k = (Comparable<? super K>) key;
  Entry<K,V> p = root;
  while (p != null) {
    int cmp = k.compareTo(p.key);
    if (cmp < 0)
      p = p.left;
    else if (cmp > 0)
      p = p.right;
    else
      return p; // <--Here
  }
  return null;
}

如果比较器从不为0,他将取消引用将为null的子分支。

旁注: 您也可以使比较器正常工作,如下所示:

Comparator<Employee> salaryComparator = (e1, e2) -> (e1.getSalary() - e2.getSalary());
TreeMap<Employee, String> trmap = new TreeMap<>(salaryComparator);

答案 1 :(得分:1)

因为当两个对象有相同的工资时,我的工资比较器永远不会返回0。

当两个对象的工资相同时,您需要修复MySalaryComp以返回零。

答案 2 :(得分:0)

正确覆盖比较器:您可以使用内置的整数比较器

<?xml version="1.0" encoding="UTF-8"?> <!-- Created with Jaspersoft Studio version 6.4.0.final using JasperReports Library version 6.4.1 --> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="subreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="4d180a2f-d30e-4c01-be4d-34208d1ab63f"> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/> <style name="Table_TH" mode="Opaque" backcolor="#F0F8FF"> <box> <pen lineWidth="0.5" lineColor="#000000"/> <topPen lineWidth="0.5" lineColor="#000000"/> <leftPen lineWidth="0.5" lineColor="#000000"/> <bottomPen lineWidth="0.5" lineColor="#000000"/> <rightPen lineWidth="0.5" lineColor="#000000"/> </box> </style> <style name="Table_CH" mode="Opaque" backcolor="#BFE1FF"> <box> <pen lineWidth="0.5" lineColor="#000000"/> <topPen lineWidth="0.5" lineColor="#000000"/> <leftPen lineWidth="0.5" lineColor="#000000"/> <bottomPen lineWidth="0.5" lineColor="#000000"/> <rightPen lineWidth="0.5" lineColor="#000000"/> </box> </style> <style name="Table_TD" mode="Opaque" backcolor="#FFFFFF"> <box> <pen lineWidth="0.5" lineColor="#000000"/> <topPen lineWidth="0.5" lineColor="#000000"/> <leftPen lineWidth="0.5" lineColor="#000000"/> <bottomPen lineWidth="0.5" lineColor="#000000"/> <rightPen lineWidth="0.5" lineColor="#000000"/> </box> </style> <subDataset name="dataset" uuid="5c388144-2819-47f9-b534-f7f6ba299c89"> <field name="patient_pid" class="java.lang.String"/> <field name="name" class="java.lang.String"/> <field name="time" class="java.lang.String"/> <field name="dov" class="java.lang.String"/> </subDataset> <parameter name="Image" class="java.io.InputStream"/> <queryString> <![CDATA[]]> </queryString> <field name="clinic_name" class="java.lang.String"/> <background> <band splitType="Stretch"/> </background> <title> <band height="64" splitType="Stretch"> <textField pattern="MMMMM dd, yyyy"> <reportElement x="450" y="-1" width="100" height="24" uuid="4d7ac980-0ba0-4efe-9081-1434c588323b"/> <textElement> <font size="11"/> </textElement> <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> </textField> <staticText> <reportElement x="410" y="0" width="50" height="22" uuid="5c4e36e4-9f79-471f-a5c5-33cae773d289"/> <textElement> <font size="10"/> </textElement> <text><![CDATA[DATE :]]></text> </staticText> <line> <reportElement x="-20" y="50" width="595" height="1" uuid="0447b856-de6a-4e34-9fbb-3154c2cde3c5"/> </line> <textField> <reportElement x="180" y="10" width="200" height="30" uuid="2e998ea5-70a4-46a0-a627-b655546dd800"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="16" isBold="true"/> </textElement> <textFieldExpression><![CDATA[$F{clinic_name}]]></textFieldExpression> </textField> <image > <reportElement x="5" y="5" width="40" height="40" uuid="e8b39492-2f94-4e0c-a970-3aafa03a3dc9"/> <imageExpression class="java.io.InputStream"><![CDATA[$P{Image}]]></imageExpression> </image> </band> </title> <pageHeader> <band height="37" splitType="Stretch"> <staticText> <reportElement x="199" y="0" width="164" height="30" uuid="cb55a61e-a4a4-40f5-a1de-e82e038ed4a1"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font size="14" isBold="true"/> </textElement> <text><![CDATA[Doctor Appointment]]></text> </staticText> </band> </pageHeader> <columnHeader> <band splitType="Stretch"/> </columnHeader> <detail> <band height="83" splitType="Stretch"> <componentElement> <reportElement x="3" y="11" width="550" height="60" uuid="c70d91e4-ae4e-44d3-926c-6a6627a502a7"> <property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/> <property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/> <property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/> <property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/> </reportElement> <jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd"> <datasetRun subDataset="dataset" uuid="75bd3e83-975c-4719-b1de-d6f6f66d0256"> <datasetParameter name="REPORT_DATA_SOURCE"> <datasetParameterExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></datasetParameterExpression> </datasetParameter> </datasetRun> <jr:column width="140" uuid="1c8bb7c9-c387-4905-95c0-e4afe5421355"> <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/> <jr:columnHeader style="Table_CH" height="30" rowSpan="1"> <staticText> <reportElement x="0" y="0" width="140" height="30" uuid="17b976bd-3434-4ab2-be8c-8d26c89c6f9b"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <text><![CDATA[Patient ID]]></text> </staticText> </jr:columnHeader> <jr:detailCell style="Table_TD" height="30"> <textField> <reportElement x="0" y="0" width="140" height="30" uuid="96797125-43b3-4736-8ceb-1eb465f312ba"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <textFieldExpression><![CDATA[$F{patient_pid}]]></textFieldExpression> </textField> </jr:detailCell> </jr:column> <jr:column width="170" uuid="cc0ebf66-9463-490a-815c-016fc08a7a9a"> <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/> <jr:columnHeader style="Table_CH" height="30" rowSpan="1"> <staticText> <reportElement x="0" y="0" width="170" height="30" uuid="491a3bcd-0c94-4c94-a3be-3ffd3dc77e2d"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <text><![CDATA[Patient Name]]></text> </staticText> </jr:columnHeader> <jr:detailCell style="Table_TD" height="30"> <textField> <reportElement x="0" y="0" width="170" height="30" uuid="437e030e-9494-4cca-9c18-5acdd62b13c9"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression> </textField> </jr:detailCell> </jr:column> <jr:column width="120" uuid="67912108-963e-4d15-88a1-ff5a586e1e9f"> <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column3"/> <jr:columnHeader style="Table_CH" height="30" rowSpan="1"> <staticText> <reportElement x="0" y="0" width="120" height="30" uuid="4e55d83d-7b00-43fe-8c9c-3e683f4ae4c2"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <text><![CDATA[Appointment Time]]></text> </staticText> </jr:columnHeader> <jr:detailCell style="Table_TD" height="30"> <textField> <reportElement x="0" y="0" width="120" height="30" uuid="aa74391c-3274-49e3-9582-236d973dcc0a"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <textFieldExpression><![CDATA[$F{time}]]></textFieldExpression> </textField> </jr:detailCell> </jr:column> <jr:column width="120" uuid="fd70d834-7bfe-49cf-8757-ffd91af0c4e2"> <property name="com.jaspersoft.studio.components.table.model.column.name" value="Column4"/> <jr:columnHeader style="Table_CH" height="30" rowSpan="1"> <staticText> <reportElement x="0" y="0" width="120" height="30" uuid="ead684cb-872c-424c-aa55-d4e5f4e3da57"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <text><![CDATA[Visit Date]]></text> </staticText> </jr:columnHeader> <jr:detailCell style="Table_TD" height="30"> <textField> <reportElement x="0" y="0" width="120" height="30" uuid="b923d0bf-2df9-442a-94bc-011413c4e7f1"/> <textElement textAlignment="Center" verticalAlignment="Middle"/> <textFieldExpression><![CDATA[$F{dov}]]></textFieldExpression> </textField> </jr:detailCell> </jr:column> </jr:table> </componentElement> </band> </detail> <columnFooter> <band splitType="Stretch"/> </columnFooter> <pageFooter> <band height="73" splitType="Stretch"/> </pageFooter> <summary> <band height="42" splitType="Stretch"/> </summary> </jasperReport>