无需更改订单即可获取唯一列表的最佳方法

时间:2019-07-05 03:23:18

标签: java

我有一个字符串列表或20,000个整数列表

现在它包含重复项...但是我不想打扰项目的顺序。

我们可以轻松地将列表转换为Set以获得唯一的Set unique = new HashSet(list);

但是,以上内容打破了项目的顺序。

什么是最好的方法?

谢谢。

5 个答案:

答案 0 :(得分:2)

您应使用java.util.LinkedHashSet来获取唯一元素,而无需更改顺序:

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
    String message = new String(delivery.getBody(), "UTF-8");

    System.out.println(" [x] Received '" + message + "'");

};
boolean autoAck = true; // acknowledgment is covered below
channel.basicConsume(QUEUE_NAME, autoAck, deliverCallback, consumerTag -> { });

另一种方法是使用Set<String> uniqueSet = new LinkedHashSet<>(list);

distinct()

但是list.stream().distinct().collect(Collectors.toList()) 在内部使用distinct()。不需要不必要的程序。

所以最好的方法是使用LinkedHashSet构造函数:

  

LinkedHashSet(Collection c)构造一个新的链接哈希   设置与指定集合相同的元素。

答案 1 :(得分:0)

如果您要消除重复项,则可以使用LinkedHashSet来保持顺序。

如果是字符串

Set<String> dedupSet = new LinkedHashSet<>();

如果是整数

Set<Integer> dedupSet = new LinkedHashSet<>();

答案 2 :(得分:0)

您可以尝试流式distinct

yourList.stream().distinct().collect(Collectors.toList());

更新1 : 据我所知,这是最好的解决方案。

  1. list.contains(element)将执行2个循环过程。一个用于迭代元素并将其添加到新列表,一个用于检查元素-> 0(n * n)

  2. new LinkedHashSet()将创建一个新的LinkedHashSet和一个新的Arraylist输出->有关内存的问题。而且我认为效果与stream distinct

Update2 :我们必须确保输出为List,而不是Set

  1. 据我所知,stream distinct在内部使用HashSet。在我们的案例中,它比LinkedHashSet(这是set接口的哈希表和链接列表的实现)效率更高。 Detail here
  2. 如果应用LinkedHashSet,源代码将类似于以下内容,因此我们有1个ArrayList和1个LinkedHashSet。

    output = new ArrayList(new LinkedHashSet(yourList));

  3. 我使用1k for循环做了一个小型基准测试。

int size = 1000000;
Random rand = new Random((int) (System.currentTimeMillis() / 1000));
List<Integer> yourList = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
    yourList.add(rand.nextInt(10000));
}
// test1: LinkedHashSet --> 35ms
new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList));
// test2: Stream distinct --> 30ms
yourList.stream().distinct().collect(Collectors.toList());

答案 3 :(得分:0)

如果您不想中断订单,请对列表进行迭代,如下所示创建新列表。

Sub Compare()
    Dim dataLength As Integer
    Dim i As Integer

    dataLength = 100

    Sheet1.Range("B2").Value = "Pass"
    For i = 1 To dataLength
        If Sheet3.Cells(1, i) <> Sheet2.Cells(i, 1) Then
            Sheet1.Range("B2").Value = "Fail"
            Exit For
        End If
    Next i
End Sub

答案 4 :(得分:0)

尝试以下代码

    public static void main(String[] args) {
    String list[] = {"9","1","1","9","2","7","2"};
    List<String> unique = new ArrayList<>();

    for(int i=0; i<list.length; i++) {
        int count = unique.size();

        if(count==0) {
            unique.add(list[i]);
        }else {
            boolean available = false;
            for(int j=0; j<count; j++) {
                if(unique.get(j).equals(list[i])) {
                    available = true;
                    break;
                }
            }

            if(!available) {
                unique.add(list[i]);
            }
        }
    }

    //checking latest 'unique' value
    for(int i=0; i<unique.size(); i++) {
        System.out.println(unique.get(i));
    }

}

它将返回9 1 2 7,但我尚未尝试多达20,000个收藏夹列表,希望没有性能问题