第一章 collection集合
1.1集合概述
###学习使用过ArrayList<E>
,????
-
集合是一种容器,可以存储多个数据。
-
数组长度固定,集合长度可变。
-
数组中存储同一类型元素,可以存储基本类型数据元素;集合存储的都是对象,而且存储的对象类型可以不一致。
collection
是所有单列集合的父接口;object
是所有类的父类
1.2集合框架
学习集合目标
- 会利用结合存储数据
- 会遍历集合,把集合中数据取出来
- 掌握每种集合的特性
collection接口:定义的是所有单列集合的共性方法
所有的单列集合都可以使用共性的方法
没有带索引的方法
List接口:1.有序。存取顺序相同。 set接口:1.不允许存储重复元素。
2.允许存取重复元素。 2.没有索引。不能使用for循环遍历
3.有索引。可以使用普通for循环遍历。
Vector集合 ArrayList集合 LinkedList集合 TreeSet集合 <-无序集合-> HashSet集合
有序集合-> LinkedHashSet集合
1.学习顶层。学习顶层中接口抽象类的共性方法,所有子类都可以使用。
2.使用底层。底层不是接口就是抽象类,无法创建对象使用,需要使用底层的子类创建对象来使用。
1.3colllection常用功能
collection
是所有单列集合的父接口,因此在collection中定义了单列集合通用的一些方法,这些方法可用于操作左右的单列集合。
public boolean add(E e)
:将给定对象添加到结合中。 //一般不用接收
public void clear()
:将集合清空。
public void remove()
:把给定的集合在当前集合中删除。
public boolean contains(E e)
:判断当前集合中是否包含给定对象。
public boolean isEmpty()
:判断当前集合是否为空。
public int size()
:返回集合中元素的个数。
public object[] toArray()
:把集合中的元素,存储到数组中。
创建集合对象,可以使用多态(父类引用指向子类对象):
Collection coll = new ArrayList<>(); //重写了toString方法
coll.add();
第二章 Iterator迭代器
-
Iterator接口
collection集合元素的通用获取方式。再去元素之前先判断集合中是否含有元素,如果有,取出;一直全部取出结束。
两个常用方法:
boolean hasnext()
; // 判断有没有元素,如果有就返回true,没有就返回false
E next()
; //返回集合中的下一个元素- Iterator是一个接口,无法直接使用;需要使用Itearator接口的实现类对象,获取实现类的方式比较特殊。collection接口中有一个方法叫Iterator,这个方法返回的式迭代器的实现类对象。
- 迭代器的使用步骤【重点】:
-
- 使用集合中的方法iterator(),获取迭代器的实现类对象,使用Iterator接口接收(多态)。
- 使用Iterator接口中的方法hashNext判断还有没有下一个元素。
- 使用Iterator接口中的方法next()取出集合中的下一个元素。
Collection<Object> coll = new ArrayList<>(); Iterator<Object> it = coll.iterator(); if ( it.hashNext() ) System.out.println( it.next() );
-
迭代器实现原理
增强for
-
底层使用迭代器;使用for循环简化书写。
-
所有的单列集合都可以使用
增强for
for (String i:list){}
练习1:遍历数组
练习2:遍历集合
第三章 泛型
3.1泛型
泛型:
generic
一种未知的数据类型;当不知道使用什么数据类型时,使用泛型。
也可以看成是一个变量,用来接收数据类型。
E e: Elment元素
T t: Type类型
创建对象的时候会确定数据类型;
会把数据类型作为参数传递,例如:把string赋值给泛型E;
不写数据类型会默认为Object类型。
-
创建集合,不使用泛型
- 好处:集合不使用泛型,默认的就是Object类型,可以存储任意类型的数据
- 弊端:不安全,会引发异常。(Object类型,向下转型会引发异常)
-
创建集合,使用泛型
- 好处:避免类型转换的麻烦
- 把运行期异常,提升到了编译期
- 弊端:泛型是什么类型,只能创建什么类型的数据。
- 好处:避免类型转换的麻烦
3.2定义使用含有泛型的类
在创建对象的时候确定泛型的数据类型
public generic<E>{
private E name;
public E getNmae(){...};
public void setName(E){...};
}
generic<String> ge = new generic<>();
//不写默认为Object类型 可以定义为String Integer类型
3.3定义使用含有泛型的方法
在调用方法的时候确定方法的数据类型
//定义含有泛型的方法
public <M> void method(M m){...}
//定义含有泛型的静态方法(类名.方法名) 不建议创建对象时使用。
public ststic <S> void method(S s){...}
3.4定义和使用含有泛型的接口
含有泛型的接口:
public interface generic<I>{
public abstract void method(I i);
}
含有泛型的接口,第一种使用方式:定义接口的实现类,【实现接口,指定接口的泛型】。
public class genericImpl1 interface generic<String>{
public void method(String str){...};
}
含有泛型的接口,第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,实现类跟着接口走。(相当于定义了一个含有泛型的类,【创建对象的时候确定泛型的类型】)
public class genericimpl2<I> interface generic<I>{
public void method(I i){...};
}
3.5泛型通配符 <?>
- 使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符
<?>
来表示,但是一旦使用通配符以后,只能使用Object类中的共性方法,集合元素自身方法无法使用。 - 只能接受数据,不能传递数据。不能创建对象时使用,只能作为方法的参数使用。
- ?代表任意数据类型。 泛型是没有继承关系的。
泛型通配符高级使用:–受限通配符
泛型的上限限定:?extends E 代表使用多个泛型只能是E类型的子类/本身
泛型的下限限定:? super E 代表使用的泛型只能是E类型的父类/本身
第四章 集合综合斗地主
案例分析:
-
准备牌。54张排存储到集合中。
- 特殊poke:大鬼,小鬼
- 52张:定义一个数组/集合,存储花色♠♥♣♦;再定义一个数组集合,存储13个数字。
循环嵌套遍历两个数组/集合,组装52张排。
-
洗牌。
-
使用集合工具类collections的方法:
static void shuffle( list<?> list) //会随机打乱集合中元素的顺序
-
-
发牌。
- 一人17张,一人一张轮流发牌。剩余三张做底牌。
- 定义4个集合,存储三个玩家的牌和底牌。(索引%3;索引>=51,发底牌)
-
看牌。
- 直接打印集合,遍历存储玩家和底牌的集合。
第五章 day3 【List Set 数据结构 collections】
###栈 队列 数组 链表 红黑树
4.1List集合
- java.util.List接口 extends collection接口
- 有序集合,存储和取出顺序一致。
- 有索引,包含一些带索引的方法。
- 允许存储重复元素。
List
常用方法:
public void add(int index, E element)
:将指定元素添加到该集合中的指定位置上。
public E get(int index)
:返回集合中指定位置上元素。
public E remove(int index)
:移除集合中指定位置上元素。
public void set(int index, E element)
:用指定元素更换集合位置上元素,返回原位置更新前元素。
4.2List的子类
4.2.1 ArrayList集合
存储的数组结构。元素增删慢,查找快。使用最多时查询数据,遍历数据。
4.2.2 LinkedList集合
- 存储的链表结构。方便元素添加和删除。
- 有序,有索引,允许重复
- 不能使用多态
LinkedList<String> ledlist = new LinkedList<>();
添加的方法:ledlist.add(int i, E e);
ledlist.push(int i, E e);
ledlist.addFirst()
ledlist.addLast()
获取的方法:ledlist.getFirst()
ledlist.getLast()
移除的方法:public E removeFirst():
public E removeLast():
public E pop()
//从此列表堆栈弹出一个元素
判空的方法:public boolean isempty();
vector
- vector类可以实现所有可增长的对象数组。
- 是所有单类数组的祖宗类。
###4.3Set接口
- 无序,无重复元素,无序列。(无法使用普通for循环)
4.3.1HashSet
-
底层是一个哈希表,查询速度特别快。
-
哈希表:
- 哈希值:10进制整数,系统随机给出。
public native int hashcode()
:返回该对象的哈希码值。
-
哈希表:同一个哈希值对应的数据超过8个,就会转化为红黑树。
-
HashSet存储自定义类型元素:
对于自定义数据类型需要覆盖重写 .equal方法 和 .hashcode方法
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if ( (obj == null)||(getClass()!= obj.getClass()) ) return false;
person per = (person) obj;
return age == per.age && Objects.equals(name, per.name);
}
@Override
public String toString() {
return this.name+":"+this.age;
}
4.3.2LinkedHashSet
- 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序。
可变参数
当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
使用格式:
修饰符 返回值类型 方法名(数据类型...变量名){}
可变参数原理:
底层是一个数组,根据传递参数的个数不同,会创建不同长度的数组,来存储这些参数传递的参数个数,可以是0,1,2...多个。
可变参数的注意事项:
-
一个方法的参数裂变,只能由一个可变参数。
-
如果方法的参数有多个,可变参数必须写在参数列表的末尾。
可变参数的终极玩法:
public void add(Object...objs){}
(但是设计类转换??Object转对应运算数据类。)
###4.4Collections
4.4.1常用功能
-
public static <T> boolean addAll(colection<T> c, T...elmnets)
:往集合中添加一些元素。 -
public static void shuffle (list<?> list)
:打乱顺序:打乱集合顺序。 -
public static <T> void sort(List<T> list)
:将集合中元素按照默认规则排序。-
【注意】使用前提,要使用sort工具,必须重写所使用类中的
comparable
接口的comparTo
确定排序规则。 -
comparator和comparable的区别:
-
comparable:自己(this)和别人(参数)比较,自己需要实现comparable接口,重写比较的规则compareTo方法。
-
comparator:相当于找一个第三方的裁判,比较两个。比较规则:o1-o2,升序 / o2-o1,降序。
Collections.sort(list2, new Comparator<person>() { @Override public int compare(person o1, person o2) { int result = o1.getAge() - o2.getAge();//按照年龄排序 if (result == 0) { result = o1.getName().charAt(0) - o2.getName().charAt(0); }//年龄一样,按照首字母排序 return result; } });
-
-
-
public static <T> void sort(list<T> list, comparator<? super T> )
:将集合中元素按照指定规则排序。
第六章 day04 Map
1.Map集合
1.1概述
collections
单列集合;Map
双列集合,两个泛型。将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值。键不能重复,值可以重复。
1.2Map常用子类
-
Map
-
HashMap<k,v>
:存储数据采用的哈希表结构,元素的存储顺序不能保证一致。由于要保证键的唯一不重复,需要重写hashcode()方法,equals()方法。 底层是数组+单向链表/红黑树。 -
LinkedHashMap<K,V>
:HashMap有个子类就是LinkedHashMap。存储和取出元素是一致的。底层是哈希表+链表(保证迭代的顺序)。
1.3Map接口中的常用方法
public V put(k key,v val)
:将指定的键与值添加到Map集合中。//key重复的话,添加新键值对,返回原value。
public V remove(object key)
:把指定的键所对应的键值对元素从集合中删除,返回被删除的元素。
public V get(object key)
:获取指定键对应的键值。
boolean containKey(object key)
:判断集合中是否包含指定键。
public Set<k> keySet()
:获取Map结合中所有的键,存储到Set集合中。
public Set<Map.Entry<k,v>> entrySet()>
:获取到Map集合中所有键值对对象的集合(Set集合)。
1.4Map集合遍历键找值方法
public Set<k> keySet()
:获取Map结合中所有的键,存储到Set集合中。
public Set<Map.Entry<k,v>> entrySet()>
:获取到Map集合中所有键值对对象的集合(Set集合)。
- Map集合的第一种遍历方式:通过键找值的方式
- 使用Map集合中的方法
map.keySet()
,把Map集合所有的key取出来,存储到一个Set集合中 - 遍历Set集合,获取Map集合中的每一个key
- 通过Map集合中的方法get(key),通过key找到value。
- 使用Map集合中的方法
1.5Entry键值对对象
-
Map集合的第二种遍历方式:
public Set<Map.Entry<k,v>> entrySet()>
:获取到Map集合中所有键值对对象的集合(Set集合)。- Map集合一创建,就会在集合中建立一个
Entry
对象,用来记录键与值(键值对对象,键与值的映射关系)–>结婚证。 -
- 使用Map集合中的方法
entrySet()
,把Map集合中多个entry对象取出来,存储到一个Set集合中。 - 遍历Set集合,获取每一个Entry对象。
- 使用Entry对象中的方法getKey() 和 getValue() 获取键与值。
- 使用Map集合中的方法
- Map集合一创建,就会在集合中建立一个
代码演示:
Set<Map.Entry<Object, Object>> entrySet = pro.entrySet();
for (Map.Entry<Object, Object> set : entrySet) {
Object key = set.getKey();
Object value = set.getValue();
System.out.println("key:" + key + " value:" + value);
}
Set<Object> keySet = pro.keySet();
System.out.println("keySet:" + keySet);
for (Object key : keySet) {
Object value = pro.get(key);
System.out.println("key:" + key + " values:" + value);
}
1.6Map集合编辑键值对方式
2种方式。
1.7HashMap存储自定义类型键值
自定义类型作为key时:必须重写equals
和hashcode
方法,确保不会重复Key值
自定义类型作为value时:无需管。
1.8LinkedHahMap
底层结构:哈希表+链表。
- key允许重复,有序集合。
1.9Map集合练习
计算一个字符串中每个字符出现的次数。
- 使用scanner获取用户输入的字符串。
- 遍历字符串,获取每一个字符。【1.String的方法toCharArray,把字符串转换为一个字符数组,遍历数组。 2. string类的方法length()+charAt() .】
- 使用Map集合中的方法判断是哦福存在Map集合中。【1. contains(key) -->(若存在,+1;如不存在,字符设为key,value+1) 2. 使用get(key)方法判断字符是否存在】
- 遍历Map集合输出结果。
1.10 HashTble
-
底层使用哈希表,线程安全,单线程,速度慢。双列集合,
-
HashMap。多线程,速度快。
-
实现了Map接口;HashTable和Vector集合都被更先进的集合取代了。vector–>arraylist hashtable–>hashmap, Hashtable不允许存空值,空key,空value都不允许。
2.补充 of方法
静态方法 of:可以为集合一次性添加多个元素。
- 使用前提:当集合中存储的元素的个数已经确定,不在改变时可以使用。也就是说在集合初始化时一次性添加好元素。后面不能再使用
add
和put
方法。 of
方法只适用于List接口,Set接口,Map接口,不适用于接口的实现类。of
方法的返回值是一个不能改变的集合,集合不能使用add,put方法添加元素,会抛出异常。- Set方法和Map方法接口在使用of方法的时候,不能有重复的元素,否则会抛出异常。
3.模拟斗地主洗牌发牌(双列模式)
-
准备牌
特殊牌+52张排( List.of(“♠”,“♥”,“♣”,“♦”) List.of(“2”,“A”,“K”…) )
容器:
- Map集合:牌的索引(key)+组装好的牌(具体一张牌)。
- List集合:只放牌的索引。
-
洗牌
- collections.shuffle(list)
-
发牌
- 一人一张,轮流发牌。集合索引%3,发给四个集合。
-
排序
- collections 的 sort(List),方法排序
-
看牌
- 查表法:遍历一个集合,获取到另外一个集合key,获取到value。