Java初学——高级API集合框架和泛型
一、集合框架
1.集合和数组的区别
数组长度固定,并且在增加和删除的方面上会降低效率。集合框架的运用会比较灵活存储的是引用数据类型或者对象,如果并不知道程序运行时会需要多少对象,或者需要 更复杂方式存储对象——可以使用Java集合框架
2.集合框架内容
图中虚线框为接口 实线框为实现类
Iterator:迭代器接口 迭代器的运用 迭代器拥有类似指针的概念 指向每个元素
//使用迭代器 配合如下代码 Iterator it=set.iterator();//获得迭代器 //通过迭代器迭代出对象 while (it.hasNext()) {//判断it集合中通过hasnext()方法将指针下移查看是否有元素 Newstitle title=(Newstitle)it.next();//通过next()方法来获得下一个元素 System.out.println(title.getAuthor()+title.getId()+title.getTitle()); }
Collection接口:存储一组 不唯一,无序的对象 主要方法有clear():清除所有元素、isEmpty():判断集合是否为空、iterator() 迭代器方法、toArray():转化数组
List:collection的子接口,存储一组不唯一,有序(插入顺序)的对象
ArrayList实现类:实现了长度可变的数组,在内存中分配连续的空间,遍历元素和随机访问元素的效率比较高。 它的扩容规则是(默认长度是10.每次长度填满是在添加第十一个时扩容1.5倍)。ArrayList的常用方法如代码
package jihe; //新闻标题类 public class NewsTitle { //新闻id 题目 作者 private int id; private String titlel; private String author; //从写构造方法 public NewsTitle() {} public NewsTitle(int id, String titlel, String author) { this.id = id; this.titlel = titlel; this.author = author; } //封装成员变量 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitlel() { return titlel; } public void setTitlel(String titlel) { this.titlel = titlel; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }
package jihe; import java.util.ArrayList; import java.util.Iterator; import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List; //新闻管理类 public class ArrayListdome { public static void main(String[] args) { //创建新闻类的对象 NewsTitle title=new NewsTitle(1, "北京市1", "wuxuew"); NewsTitle title1=new NewsTitle(2, "北京市2", "wuxuew"); NewsTitle title2=new NewsTitle(3, "北京市3", "wuxuew"); NewsTitle title3=new NewsTitle(4, "北京市4", "wuxuew"); NewsTitle title4=new NewsTitle(5, "北京市", "wuxuew"); //创建ArratListde的集合List ArrayList Lsit=new ArrayList(); //为List集合添加对象用.add方法 Lsit.add(title); Lsit.add(title1); Lsit.add(title2); Lsit.add(title3); //另一种添加方法在括号内,第一个参数指定数组下标 第二个参数添加对象 Lsit.add(1,title4); //获得集合的长度.size方法 System.out.println("新闻总数"+Lsit.size()); System.out.println("******************************************"); //获得指定下标的的内容 如下 NewsTitle titl11=(NewsTitle)Lsit.get(2); System.out.println("指定下标为2的标题内容为:"+titl11.getTitlel()); System.out.println("*****************************************"); //查找指定位置还否含有元素 Lsit.contains(2); System.out.println("下标为2的位置是否含有元素:"); System.out.println("*************************************"); //删除元素 Lsit.remove(title); // 删除指定下标元素 Lsit.remove(3); System.out.println("我删除了title 和下标为三的元素"); //遍历集合的内容 有三种方法 //方法一:for循环 System.out.println("for循环遍历"); for (int i = 0; i < Lsit.size(); i++) {//确定要去遍历多少次 NewsTitle titl=(NewsTitle)Lsit.get(i);//创建新闻类的对象接收遍历的信息 System.out.println(titl.getTitlel());//显示遍历的内容 } System.out.println("*********************************************************"); //方法二:增强for System.out.println("for增强遍历"); for (Object object : Lsit) {//将集合Lsit的内容逐个传给Object 类型的object NewsTitle titl=(NewsTitle)object;//创建新闻类的对象接受object强转成新闻类 System.out.println(titl.getTitlel());//显示内容 } //方法三:迭代器 System.out.println("迭代器遍历"); Iterator iterator=Lsit.iterator();// while (iterator.hasNext()) { NewsTitle sNewsTitle=(NewsTitle)iterator.next(); System.out.println(sNewsTitle.getAuthor()+sNewsTitle.getId()+sNewsTitle.getTitlel()); } } }
LinkedList实现类:采用链表存储方式,插入、删除元素时效率比较高 主要方法和ArrayList方法相似
package jihe; import java.awt.List; import java.util.LinkedList; public class LinkListdome { public static void main(String[] args) { //创建新闻类对象 NewsTitle title=new NewsTitle(1, "北京市1", "wuxuew"); NewsTitle title1=new NewsTitle(2, "北京市2", "wuxuew"); NewsTitle title2=new NewsTitle(3, "北京市3", "wuxuew"); NewsTitle title3=new NewsTitle(4, "北京市4", "wuxuew"); NewsTitle title4=new NewsTitle(5, "北京市5", "wuxuew"); //创建LinkedList对象 LinkedList list=new LinkedList(); //添加 list.add(title1); list.add(title2); //在当前的集合头部添加元素 list.addFirst(title4); //在当前集合末尾添加数据 list.addLast(title3); System.out.println(list.size()); for (int i = 0; i < list.size(); i++) { NewsTitle t1=(NewsTitle) list.get(i);; System.out.println(t1.getTitlel()); } for (Object object : list) { NewsTitle show=(NewsTitle)object; System.out.println(show.getTitlel()); } } }
Set:Collection的子接口 接口存储一组唯一,无序的对象 即使创建多个相同的元素但真正的值只有一个,对象会指向值得地址。set在添加元素是会自动用euqlise方法对比对象是否相等如果相等 则不会添加 将新的对象值指向已有的值。set是无序的所以不能通过索引项来实现遍历与此同时set的方法不存咋get
HashSet实现类:
package set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetDome { public static void main(String[] args) { Newstitle t1=new Newstitle("晴天", "开心", 1); Newstitle t2=new Newstitle("晴天", "开心", 2); Newstitle t3=new Newstitle("晴天", "开心", 3); Newstitle t4=new Newstitle("晴天", "开心", 4); Newstitle t5=new Newstitle("晴天", "开心", 5); HashSet set=new HashSet(); set.add(t1); set.add(t2); set.add(t3); set.add(t4); set.add(t5); //增强for实现set集合的输出 for (Object object : set) { Newstitle titlie=(Newstitle)object; System.out.println(titlie.getId()+titlie.getAuthor()+titlie.getTitle()); } //使用迭代器 Iterator it=set.iterator();//获得迭代器 //通过迭代器迭代出对象 while (it.hasNext()) { Newstitle title=(Newstitle)it.next(); System.out.println(title.getAuthor()+title.getId()+title.getTitle()); } } }
TreeSet实现类:
Map接口:存储一组键值对象,提供key到value的映射 唯一无序的
HashMap 简单练习
package jihe; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class mapdome { public static void main(String[] args) { //创建map集合 Map map=new HashMap(); map.put("US", "美国"); map.put("CN", "中国"); map.put("RU", "俄罗斯"); //显示map的元素个数 map.size(); //查看键所对应的值 String aString=(String)map.get("CN"); System.out.println(aString); //查看map中是否包含某个键 System.out.println(map.containsKey("US")); System.out.println(map.containsValue("中国")); //分别显示键的集合 值的集合 System.out.println(map.keySet()); System.out.println(map.values()); // // //删除特定键值对 // map.remove("US"); // System.out.println(map); // //清空 // map.clear(); // if (map.isEmpty()) { // System.out.println("已经清空"); // } //分别显示键和值 现取得key 在根据key获取值 Set key=map.keySet(); //方法一 System.out.println("-------------------用增强for显示键值对-----------------------------------"); for (Object object : key) { String keys=(String)object; String values=(String)map.get(keys); System.out.println(keys+values); } //方法二 System.out.println("-----------------用迭代器显示键值对-------------------------"); Iterator iterator1=key.iterator();//创建迭代器 获得key的集合 while (iterator1.hasNext()) { String keys=(String)iterator1.next(); String values=(String)map.get(keys); System.out.println(keys+values); } //拿到键值对 在从中取值 System.out.println("---------------用键值对直接显示-----------------"); Set meMap=map.entrySet();//通过方法拿到键值对的集合 for(Object obj:meMap){//增强for用来遍历键值对 Map.Entry meEntry=(Map.Entry)obj;//map中的每一对键值对 Object key1=meEntry.getKey();//取出键 Object valueses=meEntry.getValue();//取出值 System.out.println((String)key1+(String)valueses);//强转string打印 } } }
collections工具类自定义排序1.给谁排序就谁去实现comparable接口 添加方法编写比较规则 当前学员对象和返回对象比比较规则是 当前对象相等返回0 当前学号比实参大返回1小于返回-1
public class CollectionsDemo { public static void main(String[] args) { Student student1=new Student(); student1.setNumber(5); Student student2=new Student(); student2.setNumber(2); Student student3=new Student(); student3.setNumber(1); Student student4=new Student(); student4.setNumber(4); ArrayList<Student> list=new ArrayList<Student>(); list.add(student1); list.add(student2); list.add(student3); list.add(student4); System.out.println("-------排序前-------"); Iterator<Student> iterator=list.iterator(); while(iterator.hasNext()){ Student stu=iterator.next(); System.out.println(stu.getNumber()); } //使用Collections的sort方法对list进行排序 System.out.println("-------排序后-------"); Collections.sort(list); iterator=list.iterator(); while(iterator.hasNext()){ Student stu=iterator.next(); System.out.println(stu.getNumber()); } } }
package entity; public class Student implements Comparable{ private int number=0; //学号 private String name=""; //学生姓名 private String gender=""; //性别 public int getNumber(){ return number; } public void setNumber(int number){ this.number=number; } public String getName(){ return name; } public void setName(String name){ this.name=name; } public String getGender(){ return gender; } public void setGender(String gender){ this.gender=gender; } public int compareTo(Object obj){ Student student=(Student)obj; if(this.number==student.number){ return 0; //如果学号相同,那么两者就是相等的 }else if(this.number>student.getNumber()){ return 1; //如果这个学生的学号大于传入学生的学号 }else{ return -1; //如果这个学生的学号小于传入学生的学号 } } }
二、泛型
自jdk5之后建议用泛型,在编码中如果强制转换出现错误那么会影响程序异常,因此为解决这个问题泛型来解决,将对象的类型作为参数,指定到其他类或者方法上,从而保证类型转换的安全性和稳定性。泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参)然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,
操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
1.泛型的作用
List arrayList = new ArrayList(); arrayList.add("aaaa"); arrayList.add(100); for(int i = 0; i< arrayList.size();i++){ String item = (String)arrayList.get(i); Log.d("aaa","item = " + item); }
会报错
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
在代码加入泛型后
List<String> arrayList = new ArrayList<String>(); ... //arrayList.add(100); 在编译阶段,编译器就会报错