
List、Set 和 Map 的区别:
| 集合 | List | Set | Map |
|---|---|---|---|
| 元素顺序 | 有序 | 无序 | key无序、value无序 |
| 元素是否可重复 | 可重复 | 不可重复 | key不可重复、value可重复 |
List 中存储的元素有序,指的是读出的顺序与存入的顺序是一致的。
①可以允许重复的对象;
②可以插入多个 null 元素;
③是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序;
④常用的实现类有 ArrayList、LinkedList 和 Vector;ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
package collection;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** List集合* List集合的特点是可以存放重复元素且有序* 其提供了一组通过下标操作元素的方法* java.util.List是一个接口* 常用实现类:* java.util.ArrayList:内部使用数组实现,查询元素性能更好* java.util.LinkedList:内部使用链表实现,增删元素性能更好,首尾增删元素性能最佳*/
public class ListDemo1 {public static void main(String[] args) {List list = new ArrayList<>();
// List list = new LinkedList<>();list.add("one");list.add("two");list.add("three");list.add("four");list.add("five");System.out.println(list);/*E get(int index)获取指定下标处的元素*///获取List集合第三个元素String e = list.get(2);System.out.println(e);for(int i=0;iSystem.out.println(list.get(i));}/*E set(int index,E e)将给定元素设置到指定位置,返回值为被替换的元素*///[one,two,six,four,five]String old = list.set(2,"six");System.out.println(list);System.out.println(old);/*结合get,set方法,实现集合反转提示:正数下标是i的话,倒数下标算法:list.size()-1-i交换次数:size/2*//*[five,two,six,four,one]0 1 2 3 4|________||_________________|i取值范围:0,10-----41-----32是中间元素不需要交换*/for(int i=0;ie = list.get(i);//获取正数位置上的元素//将正数位置元素设置到倒数位置上,返回值为被替换的原倒数位置元素e = list.set(list.size()-1-i,e);list.set(i,e);//将原倒数位置元素设置到正数位置上}System.out.println(list);//[five,four,six,two,one]/*java.util.Collections是集合的工具类,提供了多个静态方法便于我们操作集合.reverse()方法用于反转List集合.*/Collections.reverse(list);System.out.println(list);}
}
package collection;import java.util.ArrayList;
import java.util.List;/*** List集合提供了一对重载的add,remove方法,也是通过下标进行相关操作*/
public class ListDemo2 {public static void main(String[] args) {List list = new ArrayList<>();list.add("one");list.add("two");list.add("three");list.add("four");list.add("five");System.out.println(list);/*void add(int index,E e)插入操作,将给定元素插入到指定位置*///[one,two,three,six,four,five]list.add(3,"six");System.out.println(list);/*E remove(int index)删除并返回指定位置的元素*///[one,two,six,four,five]String old = list.remove(2);//删除第三个元素System.out.println(list);System.out.println("被删除的元素是:"+old);}
}
package collection;import java.util.ArrayList;
import java.util.List;/*** 获取子集操作*/
public class ListDemo3 {public static void main(String[] args) {List list = new ArrayList<>();for(int i=0;i<10;i++){list.add(i);}System.out.println(list);/*List subList(int start,int end)获取当前List集合中指定范围内的子集.下标含头不含尾.*///获取[3-7]List subList = list.subList(3,8);System.out.println(subList);//遍历集合,将每个元素取出(get方法)后乘以10在设置回去(set方法)//[30,40,50,60,70]for(int i=0;iint num = subList.get(i);//i:0 num:3num = num * 10;//num:30subList.set(i,num);//[30,4,5,6,7]}System.out.println(subList);//对子集的操作就是对原集合的操作System.out.println(list);//删除集合中2-8这部分?list.subList(2,9).clear();System.out.println(list);}
}
package collection;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;/*** List集合的排序* Collections提供了一个静态方法sort,可以对List集合进行自然排序(从小到大)*/
public class SortListDemo {public static void main(String[] args) {Random random = new Random();List list = new ArrayList<>();for(int i=0;i<10;i++){list.add(random.nextInt(100));}System.out.println(list);Collections.sort(list);//排序System.out.println(list);Collections.shuffle(list);//乱序System.out.println(list);}
}
package collection;/*** 表示直角坐标系的一个点*/
public class Point {private int x;private int y;public Point(int x, int y) {this.x = x;this.y = y;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}@Overridepublic String toString() {return "Point{" +"x=" + x +", y=" + y +'}';}
}
package collection;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;/*** 排序自定义元素的集合*/
public class SortListDemo2 {public static void main(String[] args) {List list = new ArrayList<>();list.add(new Point(3,4));list.add(new Point(13,45));list.add(new Point(5,6));list.add(new Point(79,98));list.add(new Point(34,2));System.out.println(list);/*注:compare 比较 comparable可比较的Collections.sort(List list)该方法对集合进行自然排序的前提是,该集合中的元素必须实现了接口:Comparable,否则编译不通过.当我们直接使用上述方式排序某个集合时,若报错,则不使用该方式.不推荐我们定义的类型作为元素时,为了排序必须实现接口Comparable因为它对我们的程序造成了侵入性.侵入性:当我们使用某个类提供的方法时,该方法反过来要求我们为其修改其他额外地方的代码,此为侵入性.*/
// Collections.sort(list);/*Collections提供了一个重载的sort方法,该方法不要求元素必须实现Comparable接口,而是在使用sort方法时临时传入一个比较规则该比较规则类需要实现接口:Comparator*/
// Comparator c = new Comparator() {
// public int compare(Point o1, Point o2) {
// //比较规则:点到原点的距离长的大
// int len1 = o1.getX()*o1.getX()+o1.getY()*o1.getY();
// int len2 = o2.getX()*o2.getX()+o2.getY()*o2.getY();
// return len1-len2;
// }
// };
// Collections.sort(list,c);Collections.sort(list,new Comparator() {public int compare(Point o1, Point o2) {int len1 = o1.getX()*o1.getX()+o1.getY()*o1.getY();int len2 = o2.getX()*o2.getX()+o2.getY()*o2.getY();return len1-len2;}});System.out.println(list);}
}
package collection;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;/*** 排序字符串*/
public class SortListDemo3 {public static void main(String[] args) {List list = new ArrayList<>();list.add("范老师");list.add("刘桑");list.add("小泽老师");System.out.println(list);
// Collections.sort(list);Comparator c = new Comparator() {public int compare(String o1, String o2) {
// return o1.length()-o2.length();return o2.length()-o1.length();//反过来减就是降序}};Collections.sort(list,c);System.out.println(list);}
}
答案:
(1)ArrayList 是实现了基于动态数组的数据结构,LinkedList 基于链表的数据结构。
(2)对于随机访问 get 和 set,ArrayList 觉得优于 LinkedList,因为 LinkedList 要移动指针。
(3)对于新增和删除操作 add 和 remove,LinkedList 比较占优势,因为 ArrayList 要移动数据。若只对单条数据插入或删除, ArrayList 的速度反而优于 LinkedList。但若是批量随机的插入删除数据,LinkedList 的速度大大优于 ArrayList. 因为 ArrayList 每插入一条数据,要移动 插入点及之后的所有数据。
Set 存储的元素是无序的,这里的无序指的是存入的顺序与输出的顺序可能是不一致的。
①不允许重复对象;
②无序容器,你无法保证每个元素的存储顺序,TreeSet 通过 Comparator 或者 Comparable 维护了一个排序顺序;
③只允许一个 null 元素;
④Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet;
最流行的是基于 HashMap 实现的 HashSet;
TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
答案:
HashSet 是采用 hash 表来实现的。其中的元素没有按顺序排列,add()、remove()以及 contains()等方法都是复杂度为 O(1)的方法。
TreeSet 是采用树结构实现(红黑树算法)。元素是按顺序进行排列,但是 add()、remove()以及 contains()等方法都是复杂度为 O(log (n))的方法。它还提供 了一些方法来处理排序的 set,如 first(), last(), headSet(), tailSet()等等。
Map 存储的元素是键值对(key-value),键和值都是无序的,即存入顺序与输出顺序可能都不一样。
①Map 不是 Collection 的子接口或者实现类,Map 是一个接口;
②Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的;
③TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序;
④Map 里你可以拥有随意个 null 值,但最多只能有一个 null 键;
⑤Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap 最常用)
package map;import java.util.HashMap;
import java.util.Map;/*** Map 查找表* Map是JAVA集合框架中的一员。但是并不继承自java.util.Collection接口!!!!** Map体现的样子是一个多行两列的表格,其中左列为key,右列为value。* Map总是根据key-value对的形式保存数据,且总是根据key获取对应的value* Map中可以使用null做为key或value。* Map要求key是不允许重复的(equals比较)** Map本身是一个接口* 常用的实现类:* java.util.HashMap:基于散列算法实现的Map,也称为散列表。当今查询速度最快的数据结构。* java.util.TreeMap:基于二叉树实现的Map。**/
public class MapDemo1 {public static void main(String[] args) {Map map = new HashMap<>();/*V put(K k,V v)向Map中添加一组键值对。由于Map中的key不允许重复,所以如果使用Map已有的key存放新的value时,则是替换value操作并将被替换的value返回。如果没有任何替换时,返回值为null。*///如果Map的value是包装类类型时,要用包装类定义的变量接收返回值,避免使用基本类型因自动拆箱导致空指针!Integer v = map.put("语文",99);System.out.println(v);map.put("数学",98);map.put("英语",97);map.put("物理",96);map.put("化学",99);System.out.println(map);//会将数学原来对应的值98替换并返回。v = map.put("数学",60);System.out.println(v);//98System.out.println(map);/*V get(Object key)根据给定的key获取对应的value如果给定的key不存在,则返回值为null*/v = map.get("英语");System.out.println(v);v = map.get("体育");System.out.println(v);/*返回当前Map中的元素个数。每组键值对算一个元素。*/int size = map.size();System.out.println("size:"+size);/*V remove(Object key)删除Map中指定的key对应的这组键值对。返回值为这个key对应的value。*/v = map.remove("英语");System.out.println(v);System.out.println(map);/*boolean containsKey(Object key)判断当前Map是否包含给定的keyboolean containsValue(Object value)判断当前Map是否包含给定的value*///判断当前Map是否包含key:"数学"boolean ck = map.containsKey("数学");System.out.println("包含key:"+ck);boolean cv = map.containsValue(99);System.out.println("包含value:"+cv);//清空Mapmap.clear();System.out.println(map);}
}
package map;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** Map的遍历* 遍历Map有三种方式:* 1:遍历所有的key* 2:遍历每一组键值对* 3:遍历所有的value(相对不常用)*/
public class MapDemo2 {public static void main(String[] args) {Map map = new HashMap<>();map.put("语文",99);map.put("数学",98);map.put("英语",97);map.put("物理",96);map.put("化学",99);System.out.println(map);/*遍历所有的keySet keySet()将当前Map中所有的key以一个Set集合形式返回。遍历这个集合就等同于遍历了所有的key*/Set keySet = map.keySet();for(String key : keySet){System.out.println("key:"+key);}/*遍历每一组键值对Set entrySet()将当前Map中每一组键值对以一个Entry形式表示,并最终以Set集合形式返回所有键值对Entry提供了两个常用方法:K getKey()V getValue()来获取其表示的这组键值对的key和value*/Set> entrySet = map.entrySet();for(Map.Entry entry: entrySet){String key = entry.getKey();Integer value = entry.getValue();System.out.println(key+":"+value);}/*遍历所有的valueCollection values()将当前Map中所有的value以一个集合形式返回*/Collection values = map.values();for(Integer value : values){System.out.println("value:"+value);}/*JDK8之后集合框架的成员都支持了基于lambda表达式遍历元素的方法:forEach()*///遍历集合values.forEach(e-> System.out.println(e));
// values.forEach(System.out::println);//遍历Mapmap.forEach((k,v)-> System.out.println(k+":"+v));}
}
答案:
(1)线程安全性不同:
HashMap 是线程不安全的,HashTable 是线程安全的,其中的方法是 Synchronized 的,在多线程并发的情况下,可以直接使用 HashTable,但是使用 HashMap 时必须自己增加同步处理。
(2)是否提供 contains 方法:
HashMap 只有 containsValue 和 containsKey 方法;HashTable 有 contains、containsKey 和 containsValue 三个方法,其中 contains 和 containsValue 方法功能 相同。
(3)key 和 value 是否允许 null 值:
Hashtable 中,key 和 value 都不允许出现 null 值。HashMap 中,null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null。
(4)数组初始化和扩容机制:
HashMap 初始化大小是 16 ,扩容因子默认0.75,扩容后为2倍;HashTable默认初始容量为11,扩容后为2倍+1
(5)HashTable 继承自 Dictionary 类,而 HashMap 是Map 接口的一个实现
(6)HashTable 数据结构底层是数组+链表,HashMap数据结构底层是数组+链表+红黑树
答案:
1.HashMap实现了Map接口,而HashSet实现了Set接口。
2.HashMap用于存储键值对,而HashSet用于存储对象。
3.HashMap不允许有重复的键,可以允许有重复的值。HashSet不允许有重复元素。
4.HashMap允许有一个键为空,多个值为空,HashSet允许有一个空值。
5.HashMap中使用put()将元素加入map中,而HashSet使用add()将元素放入set中。
6.HashMap比较快,因为其使用唯一的键来获取对象。
答案:
1.List特点:元素有顺序,元素可重复
2.Set特点:元素无顺序,元素不可重复(注意:元素虽然无顺序,但是元素在set中的位置是由该元素的HashCode决定的,其位置其实是固定的)
3.Map特点:元素按键值对存储,无顺序,其中key不可重复,value可以重复
1.数组定义后类型确定,长度固定。集合类型可以不固定,大小是可变的。
2.数组可以存储基本类型和引用类型的数据。集合只能存储引用类型的数据。
3.数组适合做数据个数和类型确定的场景。集合适合做数据个数不确定,且要做增删元素的场景。

下一篇:VUE3 —— 项目构建