【问题标题】:Converting LinkedHashSet to ArrayList or just using ArrayList将 LinkedHashSet 转换为 ArrayList 或仅使用 ArrayList
【发布时间】:2019-05-27 12:49:07
【问题描述】:

考虑以下代码:

final Set<String> allPaths = new HashSet<String>();
for (final String path: paths) {
        allPaths.add(path);
}
final MyData d = new MyData(new ArrayList<String>(allPaths));

MyData 是我不应该碰的一类。它应该得到一个ArrayList 作为参数。在今天之前,我们使用这种方式是因为我们不关心订单,这就是我们使用Set的原因(所以不会重复)。但是现在,我想保持元素的顺序,所以经过一番研究,我发现我可以使用数据结构LinkedHashSet 来做到这一点。所以我做了:

final LinkedHashSet<String> allPaths = new LinkedHashSet<String>();
for (final String path: paths) {
        allPaths .add(path);
}
final MyData d = new MyData(new ArrayList<String>(allPaths));

问题是,我不确定如何将LinkedHashSet 转换为ArrayList。另外,我想使用ArrayList 而不是LinkedHashSet,所以我不必转换它,但我必须遍历数组(O(n))。

我应该使用什么好的、干净和有效的方式?

【问题讨论】:

  • 更改 MyData 以使用 Collection。为什么一开始就硬编码使用ArrayList
  • 你的做法有什么问题?使用LinkedHashSet 和使用任何其他Set 创建ArrayList 应该没有区别,只是它将使用正确的迭代顺序。
  • 你现在做的有什么问题?我的意思是,从集合中创建一个列表基本上就是你所做的,这很好。和O(n) 有什么关系?我不明白这一点。
  • ...我想知道您的代码中的 paths 是什么?这是List 还是Set

标签: java arraylist linkedhashset


【解决方案1】:

只需使用public boolean addAll(Collection&lt;? extends E&gt; c) 方法,在arrayList 上,它接受任何Collection

你有你的LinkedHashSet:

final LinkedHashSet<String> allPaths = new LinkedHashSet<String>();
for (final String path: paths) {
        allPaths .add(path);
}

然后做(即使mylist不为空也可以使用):

List<String> myList = new ArrayList<>();
mylist.addAll(allPaths);

或者更简单的方法:

List<String> myList = new ArrayList<>(allPaths);

【讨论】:

  • new ArrayList&lt;String&gt;(&lt;???&gt;) 是否知道处理集合(如LinkedHashSet)?如果是这样,我的方法还能用吗?
  • @TTaJTa4 是的,这就是 Collection 接口的重点。这是一个抽象的想法,有很多实现,但它基本上是同一个东西,一个事物的集合。 Java 使用 Collection 而不是硬编码的实现(例如 ArrayList),以便能够从一个实现交换到另一个实现 - 就像在您的情况下,当您想要使用 LinkedHashSet 而不是 HashSet 时,无需重新编写您将参数传递到的方法/类。
  • addAll 只是对 OP 已经做的事情的补充。不用用了,按原来的方式用就行了。
  • @RealSkeptic 你调用使用addAll 方法,即使列表不为空,以防他需要它,正如我在回答中提到的那样。
  • 我想知道你的回答与他已经在他的问题中所做的有什么不同?!
【解决方案2】:

您为什么不直接将您的paths 转换为LinkedHashSet 那样(假设paths 是一个集合?

final MyData d = new MyData(new ArrayList<>(new LinkedHashSet<>(paths)));

如果paths是一个数组,你可以在上面的转换中使用Arrays.asList(paths)

【讨论】:

    【解决方案3】:
    @TTaJTa4 you can use the code below as an example. Both ways are fine.
    
    
    
    import java.util.ArrayList;
    import java.util.LinkedHashSet;
    import java.util.Set;
    
    public class ConvertLinkedHashSetToArrayList
    {
    
      public static void main(String[] args)
      {
        Set<String> testStrings = new LinkedHashSet<>();
        testStrings.add("String 1");
        testStrings.add("String 2");
        testStrings.add("String 3");
        testStrings.add("String 4");
        testStrings.add("String 5");
    
        System.out.println("** Printing LinkedHashSet: " + testStrings);
        ArrayList<String> linkedHashSetToArrayList1 = new ArrayList<>(testStrings);
        System.out.println("** Printing linkedHashSetToArrayList1:" + 
        linkedHashSetToArrayList1);
    
        ArrayList<String> linkedHashSetToArrayList2 = new ArrayList<>();
        linkedHashSetToArrayList2.addAll(testStrings);
        System.out.println("** Printing linkedHashSetToArrayList2:" + 
        linkedHashSetToArrayList2);
      }
    }
    

    结果如下:

    ** Printing LinkedHashSet: [String 1, String 2, String 3, String 4, String 5]
    ** Printing linkedHashSetToArrayList1:[String 1, String 2, String 3, String 4, String 5]
    ** Printing linkedHashSetToArrayList2:[String 1, String 2, String 3, String 4, String 5]
    

    点击完整 java 项目的 GitHub 链接: GitHub example

    【讨论】:

      【解决方案4】:

      如果paths 是一个集合,你可以获得一个没有重复的数组列表:

      ArrayList&lt;String&gt; p = paths.stream().distinct().collect(Collectors.toCollection(ArrayList::new));

      如果paths 是一个数组:

      ArrayList&lt;String&gt; p = Stream.of(paths).distinct().collect(Collectors.toCollection(ArrayList::new));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-26
        • 1970-01-01
        • 1970-01-01
        • 2014-05-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多