关于集合
-
单列集合(Collection [接口] 🔌 )
- 可重复(List [接口] 🔌 )
- ArrayList [实现类]
- LinkList ⛓ [实现类]
- …
- 不可重复(Set [接口] 🔌 )
- HashSet [实现类]
- LinkedHashSet [实现类]
- TreeSet [实现类]
- …
- 可重复(List [接口] 🔌 )
-
双列集合(Map [接口] 🔌 )
-
HashMap [实现类]
-
…
-
单列集合:Collection [接口]
-
常用方法:
boolean add(E e) //添加元素 boolean remove(Object o) //从集合中移除指定元素 void clear() //清空集合中元素 boolean contains(Object o) //判断集合中是否存在指定元素 boolean isEmpty() //判断集合是否为空 int size() //集合的长度,即元素个数
-
关于Collection集合的遍历
List [接口]
List特有方法:
void add(int index,E element) //在此集合的指定索引处插入指定元素
E remove(int index) //删除索引处指定元素。返回被删除的元素
E set(int index,E element) //修改指定索引处的元素,返回被修改的元素
E get(int index) //返回指定索引处的元素
关于List集合的迭代
-
ListIterator :列表迭代器,List集合特有的迭代器
- 通过List集合的listIterator( ) 方法得到。
- 继承自Iterator
- 允许朝任意方向迭代,同时允许在迭代期间修改列表
-
ListIterator 中的常用方法
- E next( ) :返回迭代中的下一个元素👇
- E previous( ) :返回迭代中的上一个元素👆
- boolean hasNext( ) :如果此元素前面还有更多元素,则返回true👇
- boolean hasPrevious :如果此元素后面还有更多元素,则返回true👆
- void add( E element ) :将指定的元素插入列表,在当前迭代元素的后面插入 (涩涩打咩 🔞)
ArrayList [实现类]
ArrayList特点:
- 底层数据结构是数组
- 查询快,增删慢
- 每个数有自己的索引,查询的时候可以根据索引来
LinkList [实现类]
LinkList特点 :
- 底层数据结构是链表
- 查询慢,增删快
- 每个数据都有一个空间用来存放下一个数据的地址,没有索引的概念,所以查询的时候要利用迭代器
LiskList的特有方法:
public void addFirst(E element) //在该列表开头添加指定元素
public void addLast(E element) //在该列表的末尾添加指定元素
public E getFirst() //返回列表中的第一个元素
public E getLast() //返回此列表的最后一个元素
public E removeFirst() //删除此列表的第一个元素并返回
public E removeLast() //删除此列表的最后一个元素并返回
Set [接口]
HashSet [实现类]
HashSet特点:
-
HashSet:对迭代顺序不做保证(迭代顺序不一定一样)
-
HashSet集合存储对象:
- 此时Object中的
hashCode( )
方法通过引用对象地址计算哈希值 - 为保证
hashCode( )
方法功能生效,最好重写hashCode( )
方法
- 此时Object中的
-
哈希表:
-
底层通过数组+链表实现
-
数组存放首元素(类)的引用,链表存放后继元素(类)也是引用
-
链表: ⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇ 数组: [元素10][元素20][元素30][元素40][元素50][元素60] | | | | | | 元素11 元素21 元素31 元素41 元素51 元素61 | | | | | | 元素12 元素22 元素32 元素42 元素52 元素62
-
LinkedHashSet [实现类]
LinkedHashSet特点:
- 由哈希表和链表实现Set接口
- 链表顺序有序,读取顺序与读取顺序一致
- 由哈希表保证元素唯一性
TreeSet [实现类]
TreeSet集合特点:
-
元素按照一定规则排序,具体规则取决于构造方法
new TreeSet< >( )
:根据其元素的自然排序进行排序new TreeSet< >(Comparator cp)
:根据指定的比较器进行排序
-
没有索引
-
不包含重复元素
关于自然排序Comparable [接口]
-
指定的类需要实现Comparable接口才能使用比较器
-
实现接口后需要重写
compareTo( )
方法-
public int compareTo(Object o){ return ... ; } //Object -> 上一个元素的对象
-
-
第一个元素不需要比较,可以直接存入集合。
-
后面的元素需要借助
compareTo( )
方法与前面的所有元素进行比较- 返回值:等于0,表示与上一个元素一样,不存储
- 返回值:大于0,表示比上一个元素更大,放在上一个元素的 [ 后面👉| 下面👇 ]
- 返回值:小于0,表示比上一个元素更小,放在上一个元素的 [ 前面👈| 上面👆 ]
例如:
-
定义一个类:类名:User 成员变量:level
public class User implements Comparable<User>{ //成员变量 public String name; public int level; //构造方法 public User(){} public User(String name,int level){ this.name=name; this.level=level; } @Override //重写Comparable的方法 public int compareTo(@NotNull User o) { return o.level-this.level; } }
-
使用User类
public class UserDemo { public static void main (String[] args){ //创建集合对象 TreeSet<User> ts = new TreeSet<User>(); //创建User对象 User user1 = new User("佐天泪子",0); User user2 = new User("御坂美琴",5); User user3 = new User("白井黑子",4); //添加对象到集合中 ts.add(user1); ts.add(user2); ts.add(user3); //输出集合对象 for (User user:ts){ System.out.println("name:"+user.name+" level:"+user.level); } } }
-
输出结果:
name:御坂美琴 level:5 name:白井黑子 level:4 name:佐天泪子 level:0
总结:
- 用TreeSet集合存储自定义对象时,无参构造使用自然排序对元素进行排序
- 自然排序,就是让所有元素实现Comparable接口,重写compareTo(T o)方法
- 重写时,一定要考虑到排序规则的主次
关于比较器排序Comparator [接口]
- 与自然比较器差不多
- 直接举例:
-
定义一个类:类名:User 成员变量:level
public class User { //成员变量 public String name; public int level; //构造方法 public User(){} public User(String name,int level){ this.name=name; this.level=level; } }
-
使用User类
public class UserDemo { public static void main(String[] args) { //创建集合对象 TreeSet<User> ts = new TreeSet<User>(new Comparator<User>() { @Override public int compare(User o1, User o2) { return o2.level-o1.level; } }); //创建User对象 User user1 = new User("佐天泪子",0); User user2 = new User("御坂美琴",5); User user3 = new User("白井黑子",4); //添加对象到集合中 ts.add(user1); ts.add(user2); ts.add(user3); //输出集合对象 for (User user:ts){ System.out.println("name:"+user.name+" level:"+user.level); } } }
-
输出结果:
name:御坂美琴 level:5 name:白井黑子 level:4 name:佐天泪子 level:0
总结:
- 用TreeSet集合存储自定义对象时,带参构造使用比较器对元素进行排序
- 指定排序器为参数,对集合进行排序
- 用匿名内部类的时候,在User类中可以不用实现接口
双列集合:Map [接口]
Map集合概述
-
``Interface Map< K , V >` K:键的类型 V:值的类型
-
键与值的对象一一对应,键的对象不能重复,一个键对应一个值
-
Map集合为接口,可以用HashMap实例化
-
举例:
//存储结构: Map<Integer,String> [Key] [Value] [001] ["坂本"] [002] ["琴里"] [003] ["纱雾"]
Map的功能
V put(K key,V value) //添加元素(if集合内有键相同的元素,else覆盖那个元素,并返回他的值的对象)
V remove(Object key) //根据键删除键值对元素,并返回被删除的值
void clear() //清空集合
boolean containsKey(Object key) //判断集合是否包含指定的键
boolean containsValue(Object value) //判断集合是否包含指定的值
boolean isEmpty() //判断集合是否为空
int size() //返回集合键值对的个数(集合长度)
V get(Object key) //根据键获得值
Set<K> keySet() //获取所有键的集合
Collection<V> values() //获取所有值的集合
Set<Map.Entry<K,V>> entrySet() //获取所有键值对的集合
-
对Set<Map.Entry<K,V>> entrySet()的个人理解
Map.Entry<K,V>
:单个键值对 结构:[Key] [Value]
<== Entry<K,V>Set<Map.Entry<K,V>>
:存放了键值对的Set集合
关于Map集合的遍历
-
先创建一个Map集合,并存储对象
Map<Integer,String> map=new HashMap<>(); map.put(173,"scp-173"); map.put(96,"scp-096"); map.put(49,"scp-046"); map.put(682,"scp-682"); map.put(106,"scp-106");
-
方法1:
/* 思路:先用keySet()方法 获取所有键的内容 再用循环和get()方法 根据键获取相对应的值 */ Set<Integer> integers = map.keySet();//获取所有键的内容 for (Integer key:integers) {//根据键获取相对应的值 String s = map.get(key); System.out.println(s); }
-
方法2:
/* 思路:利用Map集合中的entrySet()方法获取每一个键值对的Set集合 再利用循环遍历Map集合 */ //利用Map集合中的entrySet()方法获取每一个键值对的Set集合 Set<Map.Entry<Integer, String>> entries = map.entrySet(); //再利用循环遍历Map集合 for (Map.Entry<Integer,String> entry:entries) { Integer Key= entry.getKey(); String Value = entry.getValue(); System.out.println("Key:"+Key+"\t Value:"+Value); }
-
集合工具类:Collections
常见方法:
//将指定的列表按升序排序
public static <T extends Comparable<? super T>> void sort(List<T> list)
//反转指定列表中的元素顺序
public static void reverse(List<?> list)
//使用默认的随机源 随机排列指定的列表
public static void shuffle(List<?> list)