8
回答
两种方法Set转List,还有<T>List<T>是什么意思?
【寻找人气王】邀新用户免费体验华为云服务,百元话费等你拿!   
下面两个方法有什么不同?哪个好?<T>List<T>是什么意思?

1. List a= new ArrayList(List<Set>)

2.public static <T>List<T> convertSetToList(Set<T> set){
List<T> list = new ArrayList<T>();
if(set!=null && set.size()>0){
for(T t : set){
list.add(t);
}
}
return list;
}
举报
Ken
发帖于6年前 8回/10K+阅
共有8个答案 最后回答: 5年前
第一个那个应该是:
List list = new ArrayList(set)吧?
实际对应的构造方法是 ArrayList(Collection c)
内部是使用数组复制(System.arraycopy)实现的

第二个那个是返回泛型类型的方法声明,实现是靠循环,而且再循环中还可能会扩展数组长度。

所以一定是第一种快,具体可以看测试代码:

import java.util.*;

/**
 *
 * @author Jeky
 */
public class Set2ListTest {

    public static final long TIME = 10000L;

    public static void main(String[] args) {
        Set<String> set = new HashSet<String>();
        for (int i = 0; i < 1000; i++) {
            set.add("" + i);
        }

        long start = System.nanoTime();
        for (int i = 0; i < TIME; i++) {
            List<String> list = set2List1(set);
        }
        long end = System.nanoTime();

        System.out.println(end - start);

        start = System.nanoTime();
        for (int i = 0; i < TIME; i++) {
            List<String> list = set2List2(set);
        }
        end = System.nanoTime();

        System.out.println(end - start);
    }

    public static <T> List<T> set2List1(Set<T> set) {
        return new ArrayList<T>(set);
    }

    public static <T> List<T> set2List2(Set<T> set) {
        List<T> list = new ArrayList<T>();
        if (set != null && set.size() > 0) {
            for (T t : set) {
                list.add(t);
            }
        }
        return list;
    }
}

另外,如果2中新建ArrayList的时候给定长度,速度会跟第一种差不多。
--- 共有 4 条评论 ---
Kenthanks 6年前 回复
Jeky回复 @Ken_Guan : 内存拷贝一定最快 当你使用for循环复制数组的时候,一般IDE都会告诉你应该使用System.arraycopy 6年前 回复
Jeky回复 @Ken_Guan : 第一个标志这个方法是泛型方法,第二个是List<T>是返回值 6年前 回复
Ken<T>List<T> 这个是什么意思啊?List前面还有一个<T> 6年前 回复
大部分java教程书籍里,都没有这类数据类型的教程,为什么?
--- 共有 2 条评论 ---
xoHome这个属于数据结构的范畴,在JAVA基础入门或大全类的书籍里是没有讲的。你去看看JAVA数据结构书籍肯定能找到。 至于泛型的应用,得到实践类的书上找,很多书都是讲基础,这类泛型方法在于灵活运用。 6年前 回复
Ken伱是说泛型? 6年前 回复

第二种效率高些,第一种的内部实现为内存拷贝,就是复制数组。而你第二种方式只是循环插入引用。

--- 共有 5 条评论 ---
王正航回复 @xoHome : 你这理解才叫错了,第二种方法是2个以上有数组,而且如果超过ArrayList初始化配的数组长度,所以需要对数组进行增长,这时候会产生N个数组。 另外System.arraycopy也是浅拷贝,只拷贝内存的引用而已,没有调用clone进行深拷贝,否则你想想如果用System.arraycopy拷贝没有实现clone方法的对象岂不出错了 5年前 回复
kidding明显第一种好。第一种底层使用的System.arraycopy内存拷贝 5年前 回复
Ken回复 @Ken_Guan : thanks 6年前 回复
xoHome回复 @Ken_Guan : 速度上你可以参考 @Jeky 的,内存复制时间上可能快一些,我这里理解的效率是整体的,在一个未知大小的ArrayList赋值操作中,采用循环插入引用较多,数组内存拷贝相对比来说应用较少。 两者的区别:执行过后一是内存中存在两个数组;二则只存在一个,两个数组元素指向同一份对象。前者考虑时间,后者考虑内存占用。 6年前 回复
Ken内存拷贝不是应该快点? 6年前 回复

引用来自“倾心静听”的答案

我也想知道前面一个<T>是个什么意思
上面有人说了:第一个<T>表示该方法是泛型方法,第二个是List<T>是返回值
泛型方法, 如果没有这个<T>的定义,在后面参数中使用泛型就会报错。可以认为是一种约定,当然这个泛型T 还可以写成一些类的子类。 <T extends FatherClass> 
// 参考 Java java.util.Collections 源码
public static <T> void sort(List<T> list, Comparator<? super T> c) {
        Object[] a = list.toArray();
        Arrays.sort(a, (Comparator)c);
        ListIterator i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set(a[j]);
        }
    }
顶部