是否有更简洁的方法来减少这个多维字节数组以删除重复项



我正试图找到一种方法来删除重复条目从字节数组'byte[][]'返回为'新字节[][]'。代码,因为我有它现在似乎工作,但看起来真的很丑,我想知道是否有人知道任何更好的技巧来改进它。我创建的函数如下所示:

private byte[][] filterByteArrayValues(final byte[][] values)
{
    final ArrayList<byte[]> listOfBytes = new ArrayList<byte[]>();
    final ArrayList<String> listOfCrc32 = new ArrayList<String>();
    for (final byte[] value : values)
    {
        final String crc = this.generateCheckSum(value);
        if (!listOfCrc32.contains(crc))
        {
            listOfCrc32.add(crc);
            listOfBytes.add(value);
        }
    }
    final byte[][] output = new byte[listOfBytes.size()][];
    for (int i = 0; i < listOfBytes.size(); i++)
    {
        output[i] = listOfBytes.get(i);
    }
    return output;
}

我最大的遗憾是我如何重建'byte[][]'的返回值。我很确定有更好的办法,但我想不出来。我也瞄准JRE1.8。

假设您对CRC不产生假阳性有信心,或者您对消除此类假阳性的后果感到满意,那么做同样事情的另一种方法是使用HashMap:

private byte[][] filterByteArrayValues(final byte[][] values) {
    final Map<String,byte[]> res = new HashMap<>();
    for (final byte[] value : values) {
        res.put(generateCheckSum(value), value);
    }
    return res.values().toArray(new byte[res.size()][]);
}

字节数组的相对顺序可能会改变,而不是由代码生成的数组的第一个出现,您将得到最后一个。

如果您不喜欢重新排序,使用您的方法,但将ArrayList<String>替换为HashSet<String>,使您的滤波为O(n)而不是当前的O(n2)。

如果不希望出现误报,则需要围绕byte[]数组构建一些基础设施,以使它们适合在散列容器中使用:

class Mva { // Multi-valued attribute
    private final byte[] data;
    public Mva(byte[] data) { this.data = data; }
    @Override
    public int hashCode() {
        // return CRC similar to your generateCheckSum
    }
    @Override
    public boolean equals(Object other) {
        // Cast other to Mva, and compare individual values in data[]
    }
}

现在您可以使用LinkedHashSet<Mva>来消除重复,同时保持相对顺序,并且没有消除误报的风险。

private byte[][] filterByteArrayValues(final byte[][] values) {
    final Set<Byte[]> set = new HashSet<Byte[]>();
    for (final byte[] value : values) {
        set.add(value);
    }
    return set.toArray();
}

以下是您的一些优化方法:

private byte[][] filterByteArrayValues(final byte[][] values) {
    final Map<String, Integer> map = new HashMap<>();
    for (int i = 0; i < values.length; ++i) {
        map.put(generateCheckSum(value), i);
    }
    Integer[] validInexes = map.values().toArray(new Integer[map.size()]);
    byte[][] out = new byte[validInexes.length][];
    for (int i = 0; i < validInexes.length; ++i) {
        out[i] = values[validInexes[i]];
    }
    return out;
}

但是覆盖equalshashCode,只是把每个值放入HashSet似乎是更好的主意。

相关内容

  • 没有找到相关文章

最新更新