一、Collection
1.特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
2.集合的体系机构:
单列集合(Collection)、双列集合(Map)【接口】
(1) 单列集合(Collection)
① list(可重复的)【接口】
ArrayList【实现类】底层是数组,查询快,增删慢
LinkedList【实现类】底层是链表,增删快,查询慢
特有方法
public void addFirst(E e);在该列表开头插入指定的元素
public void addLast(E e);将指定的元素追加到此列表的末尾
public E getFirst();返回此列表中的第一个元素
public E getLast()public E getFirst();返回此列表中的最后一个元素
public E removeFirst();从此列表中删除并返回第一个元素
public E removeLast();从此列表中删除并返回最后一个元素
.........【实现类】
② set(不可重复的)【接口】
HashSet【实现类】
TreeSet【实现类】
.........【实现类】
(2)Collection集合概述
1)是单列集合的顶成接口,他表示一组对象,这些对象也称为Collsction的元素
2)JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
3)创建Collection集合的对象
多态的形式(提供List和Set实现类)
具体的实现类ArrayList;Collection<String> c=new ArrayList<String>();
(3)Collection集合常用方法
boolean add(E e);添加元素
boolean remove(Object o);从集合中移除指定的元素
void clear();清空集合中的元素
boolean contains(Object o); 判断集合中是否存在指定的元素
boolean isEmpty();判断集合是否为空
int size();集合的长度,也就是集合中元素的个数
(4)Collection集合的遍历
Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
while (it.hasNext()) {//判断集合中是否有元素 String s = it.next(); System.out.println(s); }
it.hasNext()判断迭代后集合中是否有元素,返回一个布尔值
(一)List集合
1. 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
2.集合中元素可以重复;Set不能重复
3. 特点
(1)可以通过索引访问元素
(2)可以存储重复元素
(3)元素存取有序,取出顺序与存入顺序相同
4. 方法:add();remove();set();get()
5.并发修改异常:Iterator迭代器实际修改次数与预期修改次数不一样产生的;解决办法:采用for()循环遍历
6.ListIterator迭代器
(1)通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
(2)用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
(3)Listlterator中的常用方法
①next():返回迭代中的下一个元素
②hasNext():如果迭代具有更多元素,返回true
③E previous():返回列表中上一个元素
④hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,返回true
⑤add():插入元素
7.增强for循环
(1)作用:简化数组和Collection集合的遍历
①实现iterable接口的类允许其对象成为增强for语句的目标
②内部原理是一个Iteration迭代器
(2)格式:for(元素数据类型 变量名 : 数组/集合对象名) { 循环体; }
8.数据结构
(1)栈
进栈、出栈(先进后出)
(2)队列
入队列、出队列(先进先出)
(3)数组:查询快,增删慢
(4)链表:头节点+下一个元素地址(增删快、查询慢)
(二)Set集合
1.Set集合特点:
(1)元素存取无序
(2)没有索引、只能通过迭代器或增强for循环遍历
(3)不能存储重复元素
2.哈希值
(1)是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
(2)获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
(3)哈希值的特点
①同一个对象多次调用hashCode()方法返回的哈希值是相同的
②默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
③字符串的哈希值是相同的,重写了hashCode()方法
3. 哈希集合HashSet
(1) 特点:
1)底层是哈希表
2)对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
3)没有带索引的方法,所以不能使用普通for循环遍历,只能通过迭代器和增强for循环
4)由于是Set集合,所以是不包含重复元素的集合
元素的唯一性
1)根据HashSet创建对象的,对象哈希值判断是否相同,不同直接存入,相同进一步判断
2)所在位置元素的哈希值与需要加入的元素的哈希值进行比较,不同直接加入,相同进入第三步
3)两元素之间的哈希值相同,就通过.equals()方法比较两元素的内容是否相同,不同则存入,相同则不存入,确保了元素的唯一性
4.LinkedHashSet集合
(1)特点
①哈希表和链表实现的Set接口,具有可预测的迭代次序
②由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
③由哈希表保证元素唯一,也就是说没有重复的元素
5.TreeSet集合
(1) 特点
①元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator) :根据指定的比较器进行排序
②没有带索引的方法,所以不能使用普通for循环遍历
③由于是Set集合,所以不包含重复元素的集合
(2)Comparable自然排序
①用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
②自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
③重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
(3)Comparable比较器排序(带参构造方法)
①用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
②比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
③重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
(三)泛型
1.泛型概述:它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型;它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
2. 泛型定义格式
(1) <类型>:指定一种类型的格式。这里的类型可以看成是形参
(2)<类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参
(3)将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
3.泛型的好处
(1) 把运行时期的问题提前到了编译期间
(2)避免了强制类型转换
4.应用
(1) 修饰符 class 类名<类型> { }
(2) 修饰符 <类型> 返回值类型 方法名(类型 变量名) { }
(3) 修饰符 interface 接口名<类型> { }
5.类型通配符
(1) 作用:为了表示各种泛型List的父类,可以使用类型通配符
(2) 类型通配符的分类
①类型通配符:<?>
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
②类型通配符上限:<? extends 类型>
List<? extends Number>:它表示的类型是Number或者其子类型
③类型通配符下限:<? super 类型>
List<? super Number>:它表示的类型是Number或者其父类型
6. 可变参数
(1)可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
(2)可变参数定义格式
修饰符 返回值类型 方法名(数据类型… 变量名) { }
(3)可变参数的注意事项
这里的变量其实是一个数组
如果一个方法有多个参数,包含可变参数,可变参数要放在最后
(4)可变参数的使用
①Arrays工具类中有一个静态方法:
public static <T> List<T> asList(T... a):返回由指定数组支持的固定大小的列表
返回的集合不能做增删操作,可以做修改操作
②List接口中有一个静态方法:
public static <E> List<E> of(E... elements):返回包含任意数量元素的不可变列表
返回的集合不能做增删改操作
③Set接口中有一个静态方法:
public static <E> Set<E> of(E... elements) :返回一个包含任意数量元素的不可变集合
在给元素的时候,不能给重复的元素
返回的集合不能做增删操作,没有修改的方法
(四)双列集合(Map)
HashMap【实现类】
.........【实现类】
1. Map集合形式://创建集合对象 Map<K,V> K:键的类型;V:值的类型
Map<String,String> map = new HashMap<String,String>();
2. Map集合的特点
(1)键值对映射关系
(2)一个键对应一个值
(3)键不能重复,值可以重复
(4)元素存取无序
3.方法
put(K key,V value);添加元素
remove(Object key);根据键值删除对应元素
void clear();移除所有的键值对元素
boolean containsKey(Object key);判断集合是否包含指定的键
boolean containsValue(Object value);判断集合是否包含指定的值
boolean isEmpty();判断集合是否为空
int size();集合的长度,也就是集合中键值对的个数集合的长度,也就是集合中键值对的个数
4.功能
V get(Object key);根据键获取值
Set<K> keySet();获取所有键的集合
Collection<V> values();获取所有值的集合
Set<Map.Entry<K,V>> entrySet();获取所有键值对对象的集合
5. Collectios包装类
sort(集合名);将集合中的内容按照升序排列
reverse(集合名);将集合中的元素按照输入顺序反转存储
shuffle(集合名);将集合中的内容随机存储,用例扑克牌洗牌
(Map)利用Map,完成下面的功能:
从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该 年没有举办世界杯,则输出:没有举办世界杯。
package Map;
import java.util.*;
public class Test4 {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
Map<String,Team> map=new TreeMap<String, Team>();
//Team team = new Team("第一届",1930,"乌拉圭","乌拉圭");
Team team1 = new Team("第一届","1930","乌拉圭","乌拉圭");
Team team2 = new Team("第二届","1934","意大利","意大利");
Team team3 = new Team("第三届","1938","法国","乌拉圭");
Team team4 = new Team("第四届","1950","巴西","乌拉圭");
Team team5 = new Team("第五届","1954","瑞士","西德");
Team team6 = new Team("第六届","1958","瑞典","巴西");
Team team7 = new Team("第七届","1962","智利","巴西");
Team team8 = new Team("第八届","1966","英格兰","英格兰");
Team team9 = new Team("第九届","1970","墨西哥","巴西");
Team team10 = new Team("第十届","1974","前西德","西德");
Team team11 = new Team("第十一届","1978","阿根廷","阿根廷");
Team team12 = new Team("第十二届","1982","西班牙","意大利");
Team team13 = new Team("第十三届","1986","墨西哥","阿根廷");
Team team14 = new Team("第十四届","1990","意大利","西德");
Team team15 = new Team("第十五届","1994","美国","巴西");
Team team16 = new Team("第十六届","1998","法国","法国");
Team team17 = new Team("第十七届","2002","韩日","巴西");
Team team18 = new Team("第十八届","2006","德国","意大利");
Team team19 = new Team("第十九届","2010","南非","西班牙");
Team team20 = new Team("第二十届","2014","巴西","德国");
map.put(team1.getYear(),team1);
map.put(team2.getYear(),team2);
map.put(team3.getYear(),team3);
map.put(team4.getYear(),team4);
map.put(team5.getYear(),team5);
map.put(team6.getYear(),team6);
map.put(team7.getYear(),team7);
map.put(team8.getYear(),team8);
map.put(team9.getYear(),team9);
map.put(team10.getYear(),team10);
map.put(team11.getYear(),team11);
map.put(team12.getYear(),team12);
map.put(team13.getYear(),team13);
map.put(team14.getYear(),team14);
map.put(team15.getYear(),team15);
map.put(team16.getYear(),team16);
map.put(team17.getYear(),team17);
map.put(team18.getYear(),team18);
map.put(team19.getYear(),team19);
map.put(team20.getYear(),team20);
Set<String> strings = map.keySet();
for (String s:strings){
Team team = map.get(s);
System.out.println(s+team);
}
while (true) {
System.out.println("1.输入年份查询该年冠军战队\t\t2.输入战队名称查询该战队获得冠军年份");
System.out.println("\t\t\t\t\t\t3.退出");
System.out.print("请输入您要选择:");
int a=sc.nextInt();
switch (a) {
case 1:
year(map);
break;
case 2:
champion(map);
break;
case 3:
System.exit(0);
default:
System.out.println("输入错误,请重新选择:");
}
}
}
public static void year(Map<String,Team> map){
Set<String> strings = map.keySet();
while (true) {
System.out.print("请输入您需要查询的年份:");
String s = sc.next();
int in = 0;
for (String s1 : strings) {
if (s.equals(s1)) {
Team team = map.get(s1);
System.out.println(s1 + team+"\n");
return;
} else {
in++;
}
}
if (in ==strings.size()) {
System.out.println("您所查询的年份"+s+",没有举办世界杯!");
}
}
}
public static void champion(Map<String,Team> map){
Collection<Team> values = map.values();
while (true) {
System.out.print("请输入球队名称:");
String s = sc.next();
int in = values.size();
for (Team t : values) {
if (t.getChampion().equals(s)) {
Set<String> strings = map.keySet();
for (String s1 : strings) {
Team team = map.get(s1);
if (team.getChampion().equals(s)) {
System.out.println(s1);
}
}
System.out.println();
return;
} else {
in--;
}
}
if (in == 0) {
System.out.println("你输入的球队" + s + "不存在!");
}
}
}
}