集合框架和泛型
- 了解java集合体系结构
- 会使用ArrayList存储数据
- 会使用LinkedList存储数据
- 了解上述方式的区别
- 掌握set存储数据的特点
- 会通过迭代器及增强for循环遍历set
怎么用一个变量存储一个班学员信息,假定一个班容纳20个人
- 方法:不同的数组存储不同的信息
问题:数组过多,不好操作
-
方法:对象,创建一个类(Student),设置属性
创建数组,类型是创建的类的类型(Student)
最后:set
如何用一个变量存储每天的新闻信息
- 方法:对象,创建一个类(news),设置属性
创建数组,类型是创建的类的类型(news)
问题:长度不确定,不能很好的存储
最后:list
如何存储课程信息(课程号,课程名等信息),并能通过课程代号方便的获取客户层名等信息
-
多个数组
问题:不知道需要多少对象
最后:map
总结:可以使用java集合框架来解决以上问题
使用java集合框架
- 不知道程序运行需要多少对象
- 需要更复杂方式存储对象
java集合框架提供了一套性能优良,使用方便的接口和类,放在java.util包中。
collection是接口,父接口,collections是算法类
collection接口存储一组不唯一,无序的对象(可以重复)
list接口存储不唯一,有序(插入顺序)的对象(类似数组的下标)
map接口存储一组键值对象,提供key到value的映射
可以通过key找到value
key是无序且唯一的
List实现类
掌握两个实现类的特点
- ArrayList
- LinkedList
list接口存储不唯一,有序(插入顺序)的对象(类似数组的下标)
ArrayList:实现长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高
LinkedList:采用链表存储方法,插入,删除时的效率比较高
ArrayList集合类
新闻管理系统,需求
- 存储各类新闻标题(ID,名称,作者)
- 获取新闻标题的总数
- 逐条打印每条新闻标题的名称
分析:元素个数不确定,需要遍历元素
使用集合
确定存储方式
- ArrayList是List接口的一个具体实现类
- ArrayList对象实现了可变大小的数组
- 随机访问和变量时,效率高
确定存储对象
-
创建类型:新闻标题
-
包含属性:ID,名称,创建者
package day01; //新闻标题类:ID,标题,作者 public class NewsTitle { private int id; private String title; private String author; public NewsTitle(){} public NewsTitle(int id,String title,String author){ this.id=id; this.title=title; this.author=author; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } } package day01; import java.util.ArrayList; //对新闻标题的存储及操作 public class NewsMgr { public static void main(String[] args) { //创建新闻标题对象 NewsTitle title1 = new NewsTitle(1,"长城","chen"); NewsTitle title2 = new NewsTitle(2,"故宫","duan"); NewsTitle title3 = new NewsTitle(3,"冰岛","xia"); NewsTitle title4 = new NewsTitle(4,"天坛","zhou"); NewsTitle title5 = new NewsTitle(5,"小白","xu"); //创建集合对象,把标题加到集合里 ArrayList list=new ArrayList(); //等同于数组中list[0]=title1的操作 //在列表末尾添加元素 list.add(title1); list.add(title2); list.add(title3); list.add(title4); //list.add(4,title5); //在指定位置插入某个特定元素 list.add(1,title5); //操作,获取新闻标题总数,size等同于length的作用 System.out.println("新闻标题一共有"+list.size()+"条"); //逐条打印新闻标题的名称 for (int i = 0; i <list.size() ; i++) { //list.get(i);//等同于list[i],取出来的是Object对象 //强制转换 NewsTitle title=(NewsTitle)list.get(i); System.out.println(title.getTitle()); } //2.增强for for(Object obj:list){ NewsTitle title0=(NewsTitle)obj; System.out.println(title0.getTitle()); System.out.println("--------------------------"); //判断列表中是否包含某个元素 System.out.println(list.contains(title1)); //删除指定位置的元素 list.remove(0); System.out.println(list.contains(title1)); //清空集合 list.clear(); System.out.println(list.size()); //判断一个集合是否为空 System.out.println(list.isEmpty()); } } }
总结
- 增加元素add
- 获取长度size
- 获取元素get
LinkedList集合类
新闻管理系统,需求
- 可以添加头条新闻标题
- 获取头条和末条新闻标题
- 可以删除末条新闻标题
确定存储方式:
- LinkedList是list接口的一个具体实现类
- LinkedList类用于创建列表数据结构
- 插入或者删除元素师,效率高
package day01;
import java.util.LinkedList;
//对新闻标题的存储及操作
public class NewsMgr2 {
public static void main(String[] args) {
//创建新闻标题对象
NewsTitle title1 = new NewsTitle(1,"长城","chen");
NewsTitle title2 = new NewsTitle(2,"故宫","duan");
NewsTitle title3 = new NewsTitle(3,"冰岛","xia");
NewsTitle title4 = new NewsTitle(4,"天坛","zhou");
NewsTitle title5 = new NewsTitle(5,"小白","xu");
//创建集合对象,把标题加到集合里
LinkedList list=new LinkedList();
//等同于数组中list[0]=title1的操作,下标从0开始
//在列表末尾添加元素
list.add(title1);
list.add(title2);
//list.add(title3);
//list.add(title4);
//list.add(4,title5);
//在指定位置插入某个特定元素
list.add(1,title5);
//插入头条新闻新闻
list.addFirst(title3);
//操作,获取新闻标题总数,size等同于length的作用
System.out.println("新闻标题一共有"+list.size()+"条");
//逐条打印新闻标题的名称
for (int i = 0; i <list.size() ; i++) {
//list.get(i);//等同于list[i],取出来的是Object对象
//强制转换
NewsTitle title=(NewsTitle)list.get(i);
System.out.println(title.getTitle());
}
System.out.println("--------------------------");
//判断列表中是否包含某个元素
System.out.println(list.contains(title1));
//删除指定位置的元素
list.remove(0);
System.out.println(list.contains(title1));
System.out.println("--------------------------");
//清空集合
//list.clear();
//System.out.println(list.size());
//判断一个集合是否为空
//System.out.println(list.isEmpty());
//获取头条和最末条新闻标题
NewsTitle title12=(NewsTitle) list.getFirst();
System.out.println("头条"+title12.getTitle());
NewsTitle title112=(NewsTitle) list.getLast();
System.out.println("末条"+title112.getTitle());
//删除末条新闻标题
//list.removeLast();
System.out.println("新闻标题一共有"+list.size()+"条");
for (int i = 0; i <list.size() ; i++) {
//list.get(i);//等同于list[i],取出来的是Object对象
//强制转换
NewsTitle title=(NewsTitle)list.get(i);
System.out.println(title.getTitle());
}
}
}
是否可以用父类指向子类对象的方式 创建对象
可以,这种写法只能调用父子类共用的方法,不能调用子类独有的方法
总结
- 是list接口的一个具体实现类
- 用于创建链表数据结构
- 插入删除效率高
LinkedList和ArrayList的相同点
- 同为list实现类,元素有序,不唯一,长度可变
- 共有collection和list的通用方法
LinkedList和ArrayList的不同点
- ArrayList实现类长度可变的数组,在内存中连续分配空间,遍历和随机访问元素的效率高
- LinkedList采用链表存储,插入,删除效率高
set接口之HashSet
set接口存储一组唯一,无序的对象(不能重复)
HashSet是set接口常用的实现类
set中存放对象的引用
public class dd {
public static void main(String[] args) {
Set set=new HashSet();
String s1=new String("java");
String s2=s1;
String s3=new String("JAVA");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());
}
}//结果2
存放的是对象的引用,采用equals方法进行比较两个对象是否相等,相等就不存储,不等就存储
使用增强for进行遍历set
set是无序的不能使用for遍历下标实现输出
package day01;
import java.util.HashSet;
import java.util.Set;
//对新闻标题的存储及操作
public class NewsMgr3 {
public static void main(String[] args) {
//创建新闻标题对象
NewsTitle title1 = new NewsTitle(1,"长城1","chen");
NewsTitle title2 = new NewsTitle(2,"故宫2","duan");
NewsTitle title3 = new NewsTitle(3,"冰岛3","xia");
NewsTitle title4 = new NewsTitle(4,"天坛4","zhou");
NewsTitle title5 = new NewsTitle(5,"小白5","xu");
//创建集合对象,把标题加到集合里
Set set=new HashSet();
//添加set是collection的add
set.add(title1);
set.add(title2);
set.add(title3);
set.add(title4);
set.add(title5);
//操作,获取新闻标题总数,size等同于length的作用
System.out.println("新闻标题一共有"+set.size()+"条");
//增强for,打印标题内容,顺序不定
for(Object obj:set){
NewsTitle title=(NewsTitle)obj;
System.out.println(title.getTitle());
}
}
}
总结
- HashSet存储数据
- 增强for进行输出
使用Iterator遍历set
Iterator迭代器实现遍历
- 获取Iterator:collection接口的Iterator()方法
- Iterator方法
- boolean hasNext():判断是否存在另一个可访问的元素
- Object next():返回要访问的下一个元素
package day01;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
//对新闻标题的存储及操作
public class NewsMgr3 {
public static void main(String[] args) {
//创建新闻标题对象
NewsTitle title1 = new NewsTitle(1,"长城1","chen");
NewsTitle title2 = new NewsTitle(2,"故宫2","duan");
NewsTitle title3 = new NewsTitle(3,"冰岛3","xia");
NewsTitle title4 = new NewsTitle(4,"天坛4","zhou");
NewsTitle title5 = new NewsTitle(5,"小白5","xu");
//创建集合对象,把标题加到集合里
Set set=new HashSet();
//添加set是collection的add
set.add(title1);
set.add(title2);
set.add(title3);
set.add(title4);
set.add(title5);
//操作,获取新闻标题总数,size等同于length的作用
System.out.println("新闻标题一共有"+set.size()+"条");
//增强for,打印标题内容,顺序不定
for(Object obj:set){
NewsTitle title=(NewsTitle)obj;
System.out.println(title.getTitle());
}
//通过迭代器
//先获取迭代器对象
Iterator iterator=set.iterator();
//判断是否存在下一个对象
while(iterator.hasNext()){
//返回要访问的下一个对象
NewsTitle next = (NewsTitle) iterator.next();
System.out.println(next.getTitle());
}
}
}
ArrayList的遍历
Iterator iterator=list.iterator();
//判断是否存在下一个对象
while(iterator.hasNext()){
//返回要访问的下一个对象
NewsTitle next = (NewsTitle) iterator.next();
System.out.println(next.getTitle());
}
LinkedList的遍历
Iterator iterator=list.iterator();
//判断是否存在下一个对象
while(iterator.hasNext()){
//返回要访问的下一个对象
NewsTitle next = (NewsTitle) iterator.next();
System.out.println(next.getTitle());
}
集合框架和泛型小结
遍历集合的方法
有序集合:普通for遍历索引,增强for,迭代器iterator
无序集合:增强for,迭代器iterator
集合框架和泛型2
-
会使用map存取数据
- 掌握map常用方法
- 掌握遍历map
-
掌握泛型的好处及使用
-
掌握collections的使用
map接口存储一组键值对象,提供key到value的映射
可以通过key找到value
key是无序且唯一的
map中的key相当于set
初识map接口
需求:建立国家英文和中文名称之间的键值映射,应通过key对value进行操作,应该如何存储
map接口专门出来键值映射数据的存储,可以根据键实现对值的操作
- 最常用的实现类是HashMap
package day01;
import java.util.HashMap;
import java.util.Map;
public class CounteriesInfo {
public static void main(String[] args) {
//创建集合对象,并将国家信息的键值对放入集合
Map countries=new HashMap();
countries.put("China","中国");
countries.put("USA","美国");
countries.put("Japan","日本");
countries.put("France","法国");
//获取集合中存储元素的个数,返回键值对的个数
System.out.println(countries.size());
//获取集合中特定的key对应的value,强制转换
String country=(String)countries.get("China");
System.out.println(country);
}
}
put(key,value)放入数据
get(key)获取数据
size()长度
map 常用方法
键是无序的,是set
值是唯一的,是collection
package day01;
import java.util.HashMap;
import java.util.Map;
public class CounteriesInfo {
public static void main(String[] args) {
//创建集合对象,并将国家信息的键值对放入集合
Map countries=new HashMap();
countries.put("China","中国");
countries.put("USA","美国");
countries.put("Japan","日本");
countries.put("France","法国");
//获取集合中存储元素的个数,返回键值对的个数
System.out.println(countries.size());
//获取集合中特定的key对应的value,强制转换
String country=(String)countries.get("China");
System.out.println(country);
//判断集合是否包含某个国家
System.out.println("是否存在China"+countries.containsKey("China"));
System.out.println("是否存在AS"+countries.containsKey("AS"));
//删除某个特定key对应的键值对
System.out.println("是否存在USA"+countries.containsKey("USA"));
countries.remove("USA");
System.out.println("是否存在USA"+countries.containsKey("USA"));
System.out.println(countries.size());
//获取键的集合,值的结合,键值对的集合
System.out.println(countries.keySet());
System.out.println(countries.values());
System.out.println(countries);
}
}
如何遍历map集合元素
package day01;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class CounteriesInfo {
public static void main(String[] args) {
//创建集合对象,并将国家信息的键值对放入集合
Map countries=new HashMap();
countries.put("China","中国");
countries.put("USA","美国");
countries.put("Japan","日本");
countries.put("France","法国");
//获取集合中存储元素的个数,返回键值对的个数
System.out.println(countries.size());
//获取集合中特定的key对应的value,强制转换
String country=(String)countries.get("China");
System.out.println(country);
//判断集合是否包含某个国家
System.out.println("是否存在China"+countries.containsKey("China"));
System.out.println("是否存在AS"+countries.containsKey("AS"));
//删除某个特定key对应的键值对
System.out.println("是否存在USA"+countries.containsKey("USA"));
countries.remove("USA");
System.out.println("是否存在USA"+countries.containsKey("USA"));
System.out.println(countries.size());
//获取键的集合,值的结合,键值对的集合
System.out.println(countries.keySet());
System.out.println(countries.values());
System.out.println(countries);
//遍历MAP思路一:遍历key,通过可以找到value
//方法1增强for
Set keys=countries.keySet();//获取所有key
for(Object obj:keys){
String key=(String) obj;//获取map中的每一个可以
String value=(String) countries.get(key);//根据map中的每一个key,获取value
System.out.println(key+"--"+value);
}
//方法2迭代器
Iterator iterator = keys.iterator();
while (iterator.hasNext()){
String key=(String)iterator.next();//获取map中的所有key
String value=(String) countries.get(key);//根据map中的每一个key,获取value
System.out.println(key+"--"+value);
}
//思路二:遍历key,value对,然后再键值对中获取key和value
Set set=countries.entrySet();//获取map中的键值对
//遍历键值对的集合,把每个键值对--map.ENTRY(键值对类型)拿出来
//getkey返回键值对的键
//getvalue返回键值对的值
for(Object obj:set){
Map.Entry me=(Map.Entry) obj;
String key=(String)me.getKey();//获取键值对的键
String value=(String)me.getValue();//返回键值对的值
System.out.println(key+"--"+value);
}
}
}
map使用练习
需求:通过英文名。对应学员信息
package day01;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
//学生信息
public class StudentMgr {
public static void main(String[] args) {
Student stu1 = new Student("夏习清", "男");
Student stu2 = new Student("周自珩", "男");
Student stu3 = new Student("许其琛", "男");
Map stuMap = new HashMap();
stuMap.put("Buck", stu1);
stuMap.put("zhou", stu2);
stuMap.put("chen", stu3);
//输出几个学生
System.out.println("一共有" + stuMap.size() + "名学生进入外企");
System.out.println("他们是----------------------");
Set set = stuMap.entrySet();
for (Object obj : set) {
Map.Entry me = (Map.Entry) obj;
String key = (String) me.getKey();//获取键值对的键
Student student = (Student) me.getValue();//返回键值对的值
System.out.println(key + "--" + student.getName() + "--" + student.getSex());
}
//实现特定英文名对应的学生
Scanner input = new Scanner(System.in);
System.out.println("请输入你要查找的学生英文名");
String name = input.next();
if (stuMap.containsKey(name)) {
//代表里面有这个学生,根据key输出学生value
Student student = (Student) stuMap.get(name);
System.out.println(name + "--" + student.getName() + "--" + student.getSex());
}
else {
System.out.println("对不起,你要招的学生不存在");
}
}
}
泛型
JDK 5以后使用泛型改写集合框架中的所有接口和类
将对象的类型作为参数,注定到其他类或者方法上,从而暴政类型转换的安全性和稳定性(本质:参数化类型)
创建集合对象的时候直接指定类型
最开始的方式进行修改
package day01;
import java.util.ArrayList;
import java.util.Iterator;
//对新闻标题的存储及操作
public class NewsMgr {
public static void main(String[] args) {
//创建新闻标题对象
NewsTitle title1 = new NewsTitle(1,"长城","chen");
NewsTitle title2 = new NewsTitle(2,"故宫","duan");
NewsTitle title3 = new NewsTitle(3,"冰岛","xia");
NewsTitle title4 = new NewsTitle(4,"天坛","zhou");
NewsTitle title5 = new NewsTitle(5,"小白","xu");
//创建集合对象,把标题加到集合里
ArrayList <NewsTitle>list=new ArrayList<NewsTitle>();
//等同于数组中list[0]=title1的操作,下标从0开始
//在列表末尾添加元素
list.add(title1);
list.add(title2);
list.add(title3);
list.add(title4);
list.add(1,title5);
//泛型约束了集合框架的安全性,在编译时,错误的类型添加就报错
//list.add("11111");
//操作,获取新闻标题总数,size等同于length的作用
System.out.println("新闻标题一共有"+list.size()+"条");
//逐条打印新闻标题的名称
for (int i = 0; i <list.size() ; i++) {
//list.get(i);//等同于list[i],取出来的是Object对象
//不需要进行强制转换了
NewsTitle title=list.get(i);
System.out.println(title.getTitle());
}
//2.增强for
for(NewsTitle obj:list){
System.out.println(obj.getTitle());
}
Iterator<NewsTitle> iterator=list.iterator();
//判断是否存在下一个对象
while(iterator.hasNext()){
//返回要访问的下一个对象
NewsTitle next = iterator.next();
System.out.println(next.getTitle());
}
System.out.println("--------------------------");
//判断列表中是否包含某个元素
System.out.println(list.contains(title1));
//删除指定位置的元素
list.remove(0);
System.out.println(list.contains(title1));
System.out.println("--------------------------");
//清空集合
list.clear();
System.out.println(list.size());
//判断一个集合是否为空
System.out.println(list.isEmpty());
}
}
典型泛型集合 ArrayList,HashMap<K,V>
,<K,V>表示该反省集合中的元素类型
泛型集合中的数据不再转换为object
collection 类及常用方法
- 理解collections的作用
- 掌握collections的常用方法
collections类定义了一系列用于操作集合的静态方法
(不用new)
collections和collection的不同:
- 前者是集合的操作类,后者是集合接口
- collections提供的常用静态方法
- sort()排序
- binarySearch()查找
- max(),min(),查找最大,最小值
- reverse()翻转元素顺序
package day01;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionUseDemo {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("ant");
list.add("bear");
list.add("pen");
list.add("zoo");
list.add("apple");
list.add("candy");
list.add("zookeeper");
for (String s:list){
System.out.println(s);
}
//使用collections对集合进行升序排列
Collections.sort(list);
for (String s:list){
System.out.println(s);
}
//找到最大,最小值
System.out.println("集合中的最大值是"+Collections.max(list));
System.out.println("集合中的最大值是"+Collections.min(list));
//查找集合中的特定元素
System.out.println("查找特定元素位置"+Collections.binarySearch(list,"zoo"));
//反转
System.out.println("000000000000000000000000000000");
Collections.reverse(list);
for(String n:list){
System.out.println(n);
}
}
}
collections排序
- 掌握使用collections如何排序自定义数据类型的集合元素
- collections类可以对集合进行排序,查找和替换
步骤:
- 该类要实现comparable接口
- 重写compareTo()方法
package day01;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionUseDemo {
public static void main(String[] args) {
List<Student> list=new ArrayList<Student>();
Student stu1=new Student(1,"周自珩","男");
Student stu2=new Student(7,"夏知许","男");
Student stu3=new Student(3,"许其琛","男");
Student stu4=new Student(15,"夏习清","男");
list.add(stu1);
list.add(stu2);
list.add(stu3);
list.add(stu4);
for (Student stu:list){
System.out.println(stu.getNo()+"-"+stu.getName()+"-"+stu.getSex());
}
Collections.sort(list);
for(Student stu:list){
System.out.println(stu.getNo()+"-"+stu.getName()+"-"+stu.getSex());
}
}
}
package day01;
public class Student implements Comparable {
private String name;
private String sex;
public int no;
public Student(){}
public Student(int no,String name,String sex){
this.name=name;
this.sex=sex;
this.no=no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
//重写方法,定义比较规则
//学号越小,排序越靠前
//比较当前学生对象(this)和object o 比较
@Override
public int compareTo(Object o) {
Student student = (Student) o;
if (this.no == student.no) {
return 0;
} else if (this.no > student.no) {
return 1;
}
else {
return -1;
}
}
}