@Override
    public ICardinality merge(ICardinality... estimators) throws LinearCountingMergeException {
        if (estimators == null) {
            return new LinearCounting(map);
        }
        LinearCounting[] lcs = Arrays.copyOf(estimators, estimators.length + 1, LinearCounting[].class);
        lcs[lcs.length - 1] = this;
        return LinearCounting.mergeEstimators(lcs);
    }
@Test
    public void testMerge() throws LinearCountingMergeException {
        int numToMerge = 5;
        int size = 65536;
        int cardinality = 1000;

        LinearCounting[] lcs = new LinearCounting[numToMerge];
        LinearCounting baseline = new LinearCounting(size);
        for (int i = 0; i < numToMerge; i++) {
            lcs[i] = new LinearCounting(size);
            for (int j = 0; j < cardinality; j++) {
                double val = Math.random();
                lcs[i].offer(val);
                baseline.offer(val);
            }
        }

        int expectedCardinality = numToMerge * cardinality;
        long mergedEstimate = LinearCounting.mergeEstimators(lcs).cardinality();
        double error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
        assertEquals(0.01, error, 0.01);

        LinearCounting lc = lcs[0];
        lcs = Arrays.asList(lcs).subList(1, lcs.length).toArray(new LinearCounting[0]);
        mergedEstimate = lc.merge(lcs).cardinality();
        error = Math.abs(mergedEstimate - expectedCardinality) / (double) expectedCardinality;
        assertEquals(0.01, error, 0.01);

        long baselineEstimate = baseline.cardinality();
        assertEquals(baselineEstimate, mergedEstimate);
    }