public ResourceSpec subtract(final ResourceSpec other) {
        checkNotNull(other, "Cannot subtract null resources");

        if (this.equals(UNKNOWN) || other.equals(UNKNOWN)) {
            return UNKNOWN;
        }

        checkArgument(
                other.lessThanOrEqual(this),
                "Cannot subtract a larger ResourceSpec from this one.");

        Map<String, ExternalResource> resultExtendedResources = new HashMap<>(extendedResources);
        for (ExternalResource resource : other.extendedResources.values()) {
            resultExtendedResources.merge(
                    resource.getName(), resource, (v1, v2) -> v1.subtract(v2));
        }

        return new ResourceSpec(
                this.cpuCores.subtract(other.cpuCores),
                this.taskHeapMemory.subtract(other.taskHeapMemory),
                this.taskOffHeapMemory.subtract(other.taskOffHeapMemory),
                this.managedMemory.subtract(other.managedMemory),
                resultExtendedResources);
    }
@Test
    void testSubtract() {
        final ResourceSpec rs1 =
                ResourceSpec.newBuilder(1.0, 100)
                        .setExtendedResource(new ExternalResource(EXTERNAL_RESOURCE_NAME, 1.1))
                        .build();
        final ResourceSpec rs2 =
                ResourceSpec.newBuilder(0.2, 100)
                        .setExtendedResource(new ExternalResource(EXTERNAL_RESOURCE_NAME, 0.5))
                        .build();

        final ResourceSpec subtracted = rs1.subtract(rs2);
        assertThat(subtracted.getCpuCores()).isEqualTo(new CPUResource(0.8));
        assertThat(subtracted.getTaskHeapMemory().getMebiBytes()).isZero();
        assertThat(subtracted.getExtendedResource(EXTERNAL_RESOURCE_NAME))
                .contains(new ExternalResource(EXTERNAL_RESOURCE_NAME, 0.6));
    }