Java学习笔记:集合框架关系与区别

集合框架关系与区别

  • 学习参考网址https://how2j.cn/p/6235

目录

集合框架关系与区别

ArrayList与HashSet区别

是否有顺序

能否重复

ArrayList和LinkedList区别

插入数据

定位数据

HashMap和Hashtable的区别

HashSet LinkedHashSet TreeSet


ArrayList与HashSet区别

是否有顺序

  • ​​​​​​​ArrayList: 有顺序
  • HashSet: 无顺序
  • HashSet的具体顺序,既不是按照插入顺序,也不是按照hashcode的顺序。
  • 不保证Set的迭代顺序; 确切的说,在不同条件下,元素的顺序都有可能不一样
  • 换句话说,同样是插入0-9到HashSet中, 在JVM的不同版本中,看到的顺序都是不一样的。 所以在开发的时候,不能依赖于某种臆测的顺序,这个顺序本身是不稳定
     

 

package collection;
   
import java.util.ArrayList;
import java.util.HashSet;
    
public class TestCollection {
    public static void main(String[] args) {
           
        ArrayList numberList =new ArrayList();
        //List中的数据按照插入顺序存放
        System.out.println("----------List----------");
        System.out.println("向List 中插入 9 5 1");
        numberList.add(9);
        numberList.add(5);
        numberList.add(1);
        System.out.println("List 按照顺序存放数据:");
        System.out.println(numberList);
        System.out.println("----------Set----------");
        HashSet numberSet =new HashSet();
        System.out.println("向Set 中插入9 5 1");
        //Set中的数据不是按照插入顺序存放
        numberSet.add(9);
        numberSet.add(5);
        numberSet.add(1);
        System.out.println("Set 不是按照顺序存放数据:");
        System.out.println(numberSet);
           
    }
}

Java学习笔记:集合框架关系与区别_第1张图片

能否重复

  • List中的数据可以重复
  • Set中的数据不能够重复
  • 重复判断标准是:
    • 首先看hashcode是否相同
    • 如果hashcode不同,则认为是不同数据
    • 如果hashcode相同,再比较equals,如果equals相同,则是相同数据,否则是不同数据
  • 案例演示:
    • 生成50个 0-9999之间的随机数,要求不能有重复的
  • 使用Set来存放随机数,不断的向里塞,直到塞满50个位置。 因为Set有不重复的特性,所以最后得到的50个,就一定是不重复的
package collection;
 
import java.util.HashSet;
import java.util.Set;
 
public class TestCollection {
    public static void main(String[] args) {
        Set numbers =new HashSet<>();
        while(numbers.size()<50){
            int i = (int) (Math.random()*10000);
            numbers.add(i);
        }
        System.out.println("得到50个不重复随机数:");
        System.out.println(numbers);
    }
}

ArrayList和LinkedList区别

  • ArrayList 插入,删除数据慢
  • LinkedList, 插入,删除数据快
  • ArrayList是顺序结构,所以定位很快,指哪找哪。 就像电影院位置一样,有了电影票,一下就找到位置了。
  • LinkedList 是链表结构,就像手里的一串佛珠,要找出第99个佛珠,必须得一个一个的数过去,所以定位慢

Java学习笔记:集合框架关系与区别_第2张图片

插入数据

package collection;
 
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
 
public class TestCollection {
    public static void main(String[] args) {
        List l;
        l = new ArrayList<>();
        insertFirst(l, "ArrayList");
 
        l = new LinkedList<>();
        insertFirst(l, "LinkedList");
 
    }
 
    private static void insertFirst(List l, String type) {
        int total = 1000 * 100;
        final int number = 5;
        long start = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            l.add(0, number);
        }
        long end = System.currentTimeMillis();
        System.out.printf("在%s 最前面插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
    }
 
}

Java学习笔记:集合框架关系与区别_第3张图片

定位数据

package collection;
 
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
 
public class TestCollection {
    public static void main(String[] args) {
        List l;
        l = new ArrayList<>();
        modify(l, "ArrayList");
 
        l = new LinkedList<>();
        modify(l, "LinkedList");
 
    }
 
    private static void modify(List l, String type) {
        int total = 100 * 1000;
        int index = total/2;
        final int number = 5;
        //初始化
        for (int i = 0; i < total; i++) {
            l.add(number);
        }
         
        long start = System.currentTimeMillis();
 
        for (int i = 0; i < total; i++) {
             int n = l.get(index);
             n++;
             l.set(index, n);
        }
        long end = System.currentTimeMillis();
        System.out.printf("%s总长度是%d,定位到第%d个数据,取出来,加1,再放回去%n 重复%d遍,总共耗时 %d 毫秒 %n", type,total, index,total, end - start);
        System.out.println();
    }
 
}

Java学习笔记:集合框架关系与区别_第4张图片

  • 案例演示:
    • 比较 ArrayList和LinkedList 在最后面插入100000条数据,谁快谁慢?为什么
      • 直接调用add方法,就表示在最后插入数据
      • 因为是插入在最后面,所以对于数组而言,并没有一个移动很多数据的需要,所以也非常的快
      • 而链表本身就很快,无论插入在哪里
package collection;
  
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
  
public class TestCollection {
    public static void main(String[] args) {
        List l;
        l = new ArrayList<>();
        insertFirst(l, "ArrayList");
  
        l = new LinkedList<>();
        insertFirst(l, "LinkedList");
  
    }
  
    private static void insertFirst(List l, String type) {
        int total = 1000 * 100;
        final int number = 5;
        long start = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            //直接add就表示插入在最后
            l.add(number);
        }
        long end = System.currentTimeMillis();
        System.out.printf("在%s 最后面插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
    }
  
}

Java学习笔记:集合框架关系与区别_第5张图片

  • 在List的中间位置,插入数据,比较ArrayList快,还是LinkedList快,并解释为什么?
l.add(l.size()/2,number);
  • 表示在当前容器的一半的位置,插入数据
  • 在这个位置插入数据
    • 数组定位很快,插入数据比较慢
    • 链表定位很慢,插入数据比较快
  • 最后发现,当总数是10000条的时候,链表定位的总开支要比数组插入的总开支更多,所以最后整体表现,数组会更好。
  • 如果总数是1000条,结果可能就不一样了。
package collection;
   
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
   
public class TestCollection {
    public static void main(String[] args) {
        List l;
        l = new ArrayList<>();
        insertFirst(l, "ArrayList");
   
        l = new LinkedList<>();
        insertFirst(l, "LinkedList");
   
    }
   
    private static void insertFirst(List l, String type) {
        int total = 1000 * 100;
        final int number = 5;
        long start = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            //把当前容器的一半的位置,插入数据
            l.add(l.size()/2,number);
        }
        long end = System.currentTimeMillis();
        System.out.printf("在%s 最中间插入%d条数据,总共耗时 %d 毫秒 %n", type, total, end - start);
    }
   
}

  • HashMap和Hashtable的区别

  • HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
  • 区别1: 
    • HashMap可以存放 null
    • Hashtable不能存放null
  • 区别2:
    • HashMap不是线程安全的类
    • Hashtable是线程安全的类
package collection;
 
import java.util.HashMap;
import java.util.Hashtable;
 
public class TestCollection {
    public static void main(String[] args) {
         
        //HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
         
        HashMap hashMap = new HashMap();
         
        //HashMap可以用null作key,作value
        hashMap.put(null, "123");
        hashMap.put("123", null);
         
        Hashtable hashtable = new Hashtable();
        //Hashtable不能用null作key,不能用null作value
        hashtable.put(null, "123");
        hashtable.put("123", null);
 
    }
}
  • 案例演示:
使用如下键值对,初始化一个HashMap:
adc - 物理英雄
apc - 魔法英雄
t - 坦克

对这个HashMap进行反转,key变成value,value变成key
提示: keySet()可以获取所有的key, values()可以获取所有的value
package collection;
    
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
    
public class TestCollection {
    public static void main(String[] args) {
        HashMap map = new HashMap<>();
        HashMap temp = new HashMap<>();
        map.put("adc", "物理英雄");
        map.put("apc", "魔法英雄");
        map.put("t", "坦克");
         
        System.out.println("初始化后的Map:");
        System.out.println(map);
        Set keys = map.keySet();
         
        for (String key : keys) {
            String value = map.get(key);
            temp.put(value, key);
        }
        map.clear();
        map.putAll(temp);
         
        System.out.println("反转后的Map:");
        System.out.println(map);
         
    }
}
  • HashSet LinkedHashSet TreeSet

    • HashSet: 无序
    • LinkedHashSet: 按照插入顺序
    • TreeSet: 从小到大排序
package collection;
  
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
  
public class TestCollection {
    public static void main(String[] args) {
        HashSet numberSet1 =new HashSet();
        //HashSet中的数据不是按照插入顺序存放
        numberSet1.add(88);
        numberSet1.add(8);
        numberSet1.add(888);
          
        System.out.println(numberSet1);
          
        LinkedHashSet numberSet2 =new LinkedHashSet();
        //LinkedHashSet中的数据是按照插入顺序存放
        numberSet2.add(88);
        numberSet2.add(8);
        numberSet2.add(888);
          
        System.out.println(numberSet2);
        TreeSet numberSet3 =new TreeSet();
        //TreeSet 中的数据是进行了排序的
        numberSet3.add(88);
        numberSet3.add(8);
        numberSet3.add(888);
          
        System.out.println(numberSet3);
          
    }
}
  • 既不重复,又有顺序
    • 利用LinkedHashSet的既不重复,又有顺序的特性,把Math.PI中的数字,按照出现顺序打印出来,相同数字,只出现一次
package collection;
 
import java.util.LinkedHashSet;
import java.util.Set;
 
public class TestCollection {
    public static void main(String[] args) {
        Set result = new LinkedHashSet<>();
        String str = String.valueOf(Math.PI);
        // 去掉点
        str = str.replace(".", "");
        char[] cs = str.toCharArray();
        for (char c : cs) {
            int num = Integer.parseInt(String.valueOf(c));
            result.add(num);
        }
        System.out.printf("%s中的无重复数字是:%n",String.valueOf(Math.PI));
        System.out.println(result);
 
    }
}

 

你可能感兴趣的:(Java学习之路)