黑马程序员——Java基础---泛型、集合框架工具类:Collections和Arrays、JDK 1.5新特性
2015-07-29 00:17
851 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
第一部分 泛型
泛型:广泛的类型。就是给对象指定数据类型的安全机制。泛型是JDK1.5 版本以后出现的新特性。用于解决数据的安全问题。是一个安全机制。
好处:
1、将运行时期出现问题 ClassCastException,转移到了编译时期。防便于程序员解决问题。让运行时问题减少,提高安全。
2、避免了强制转换的麻烦。
泛型格式:通过 <> 尖括号来定义要操作的引用数据类型。
泛型又可以细分为:
1、泛型集合
2、泛型类
3、泛型接口
4、高级泛型
一、泛型集合
在使用java提供的对象时,什么时候写泛型呢?通常在集合框架中很常见。只要见到<>就是定义泛型。其实<>就是用来接收数据类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>尖括号中即可。
1)Demo:
二、泛型类,泛型方法和泛型接口
1) 什么时候定义泛型类?当类中需要操作的引用数据类型不确定的时候,早期定义 Object 来完成扩展,现在定义泛型来完成扩展。
2) 泛型类定义的泛型在整个类中有效。如果被方法使用,那么泛型类的对象要明确操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
3) 特殊之处:
静态不可以访问类上定义的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法中。
4) 定义泛型类:
1、可以定义泛型类:class DemoGe< T>
2、可以定义泛型方法:public < S> void show(S s)
3、可以同时定义泛型类和泛型方法。
5) Demo :
三、高级泛型
当传入的类型不确定时,可以使用通配符?。也可以理解为占位符。使用通配符的好处是可以不用明确传入的类型,这样在使用泛型类或者泛型方法时,提高了扩展性。
Demo:
第二部分 Collections和Arrays
一、Collections
1)常用方法:
1、sort 方法:给 list 集合排序,用 sort 方法。
2、max 方法:取 list 集合中的最大值。用 max 方法。
demo:
3、binarySearch:查询的字符串在集合中是否存在。返回 -1 ,表示不存在;返回 0 ,则存在。
4、fill :将list集合所有元素替换成指定元素。
fill练习:
打印结果:
5、reverseOrder :强行逆转比较器。
demo:
6、shuffle :随机排序。
7、swap :交换位置。
demo:
二、Arrays
Arrays是用于操作数组的工具类。
1)将数组转换为集合
注意:
a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。
b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
好处:可以使用集合的思想和方法来操作数组中的元素。
2)集合变数组
指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。
好处: 可以限定对元素的操作,不可以进行增删了。
第三部分 JDK 1.5的新特性
一、静态导入
1、当类名重名时。需要指定具体的包名
2、当方法重名时。指定具备所属的对象或者类。
二、方法的可变参数
1) 使用注意:可变参数,一定要定义在参数列表的后面。
2) 可变参数传递的使用方式:其实就是上一种数组的参数简写形式,不用每次都动手的建立数组对象,只要将操作的元素作为参数传递即可,隐式的将这些参数封装成了数组。
3) 可变参数的写法:public static void show2(String s,int…arr){}
三、高级 for 循环
1)格式:
for(数据类型 变量名:被遍历的集合(collection) 或者数组){
}
2)for 对集合的遍历,只能获取元素,但是不能对集合进行操作。迭代器除了对集合进行遍历,还能进行 remove 集合中元素的动作。如果是用 ListIterator,还可以在遍历过程中对集合进行增删改查的动作。
3)高级 for 循环的局限性:高级 for 有一个局限性,必须有被遍历的目标。
4)建议:在遍历数组的时候,还是希望使用传统的 for ,因为传统 for 可以定义脚标。高级for:只能对集合中的数据取出,不能做到修改集合中的元素,即使是赋值也没办法。
Demo:
四、JDK 1.5 自动装箱与拆箱
1)Integer i = 5;//自动装箱new Integer(5);
2)i = i+2; //i进行自动拆箱,变成了 int 类型,再和 2 相加,再进行装箱赋值给 i 。
3)byte范围是-128~127之间,所以Integer m,n = 128;已经超出byte范围,所以虽然看似相同,其实他们指向了两个不同的 Integer 对象。
总结
本章知识比较零碎,很多内容容易忽视,比如Collections里的reverseOrder强行逆转比较器方法,这些内容方法都是非常实用的方法,掌握它们有时候会让代码精简很多。所以任何的知识点都要引起重视,一次记不住争取第二次就能记住。
第一部分 泛型
泛型:广泛的类型。就是给对象指定数据类型的安全机制。泛型是JDK1.5 版本以后出现的新特性。用于解决数据的安全问题。是一个安全机制。
好处:
1、将运行时期出现问题 ClassCastException,转移到了编译时期。防便于程序员解决问题。让运行时问题减少,提高安全。
2、避免了强制转换的麻烦。
泛型格式:通过 <> 尖括号来定义要操作的引用数据类型。
泛型又可以细分为:
1、泛型集合
2、泛型类
3、泛型接口
4、高级泛型
一、泛型集合
在使用java提供的对象时,什么时候写泛型呢?通常在集合框架中很常见。只要见到<>就是定义泛型。其实<>就是用来接收数据类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>尖括号中即可。
1)Demo:
ArrayList<String> al = new ArrayList<String>();//加了“ <> ”。就表示泛型结构,为了定义容器的数据类型,减少出错。 al.add("java01"); al.add("java02"); al.add("java04"); al.add(2,"java03"); ListIterator<String> li = al.listIterator(); //指定迭代器的数据类型 while (li.hasNext()){ String str = li.next();//这时候就不需要强转了,避免了强制转换的麻烦 if(obj.equals("java02")){ // li.set("java002");//修改操作 // li.remove();//删除操作 } System.out.println(str);// }
二、泛型类,泛型方法和泛型接口
1) 什么时候定义泛型类?当类中需要操作的引用数据类型不确定的时候,早期定义 Object 来完成扩展,现在定义泛型来完成扩展。
2) 泛型类定义的泛型在整个类中有效。如果被方法使用,那么泛型类的对象要明确操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
3) 特殊之处:
静态不可以访问类上定义的泛型。
如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法中。
4) 定义泛型类:
1、可以定义泛型类:class DemoGe< T>
2、可以定义泛型方法:public < S> void show(S s)
3、可以同时定义泛型类和泛型方法。
5) Demo :
package fuxi1; /** * *@author XiaLei */ public class Day15Test3 { public static void main(String[] args) { } } class FanXin<T>{//定义泛型类 public void show(T t){ System.out.println("show"); } public void run(T t){ System.out.println("run"); } /* * 如果不定义泛型类,那么就需要在每一个方法后面传入具体参数,较为麻烦。例如 * public void show(String s){} * public void run(String s){} * 简化书写的同时,也出现了弊端,即泛型类一旦明确了类型,则所有的方法都要使用该类型。 */ public <W> void print(W w){//泛型类中也可以定义泛型方法。 } public static <W> void speak(){//静态方法不可以访问类上定义的泛型,因为类上的泛型必须要通过创建对象后才能实现,而静态加载出现在对象之前。 //另外注意泛型放在返回值类型前面。 } } class FanXinDemo{ public <T> void show(T t){//为了避免泛型类的以上弊端,我们可以定义泛型方法。 System.out.println("show"); } public <T> void run(T t){ System.out.println("run"); } }
三、高级泛型
当传入的类型不确定时,可以使用通配符?。也可以理解为占位符。使用通配符的好处是可以不用明确传入的类型,这样在使用泛型类或者泛型方法时,提高了扩展性。
Demo:
package fuxi1; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; /** * 泛型限定:用于泛型拓展。 * ? 通配符,也可以理解为占位符。 * ?extends E:可以接受E或者E的子类。上限。 * ?super E:可以接受E或者E的父类。下限。 *@author XiaLei */ public class Day15Test4 { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(new MyLock()); ts.add(new Student("java01")); ts.add(new Student("java08")); ts.add(new Student("java00")); ts.add(new Student("java05")); TreeSet<GoodStudent> ts1 = new TreeSet<GoodStudent>(new MyLock()); ts1.add(new GoodStudent("java--01")); ts1.add(new GoodStudent("java--08")); ts1.add(new GoodStudent("java--00")); ts1.add(new GoodStudent("java--05")); // for(Iterator<Student> it = ts.iterator();it.hasNext();){ // System.out.println(it.next().getName()); // } // for(Iterator<GoodStudent> it = ts1.iterator();it.hasNext();){//书写很麻烦 // System.out.println(it.next().getName()); // } print(ts); print(ts1);//定义一个打印方法 } public static void print(TreeSet<? extends Student> ts){//利用泛型限定简化了书写,利于程序后期扩展。 for(Iterator<? extends Student> it = ts.iterator();it.hasNext();){ System.out.println(it.next().getName()); } } } class Student{ String name; public Student(String name) { super(); this.name = name; } public String getName(){ return name; } } class GoodStudent extends Student{ public GoodStudent(String name) { super(name); } public String getName(){ return name; } } class MyLock implements Comparator<Student>{//<? super > public int compare(Student s1,Student s2){ return s1.getName().compareTo(s2.getName()); } }
第二部分 Collections和Arrays
一、Collections
1)常用方法:
1、sort 方法:给 list 集合排序,用 sort 方法。
2、max 方法:取 list 集合中的最大值。用 max 方法。
demo:
package fuxi1; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * 集合框架工具类 * 需求:利用Collections工具类给List集合排序,以及求最大值等等。 * 思路:Collections的sort方法就是专门给List集合排序的,如果需要指定比较方法可以创建比较器。 * max方法则是给出最大值,同样也可以加比较器。 *@author XiaLei */ public class Day17Test1 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("fdsa"); list.add("fda"); list.add("s"); list.add("ss"); list.add("adfss"); // Collections.sort(list);//按照字符串自然顺序排序。 // System.out.println(list); Collections.sort(list,new StrLenthCom());//创建比较器,按照字符串长度排序。 System.out.println(list); // String max = Collections.max(list,new StrLenthCom());//创建比较器,按照字符串长度求最大值。 // System.out.println(max); int index = Collections.binarySearch(list, "s",new StrLenthCom());//二分查找,如果元素不在则返回-(应插入位置角标)-1; System.out.println(index); } } class StrLenthCom implements Comparator<String>{ public int compare(String s1,String s2){ if(s1.length()>s2.length()) return 1; if(s1.length()<s2.length()) return -1; else return s1.compareTo(s2); } }
3、binarySearch:查询的字符串在集合中是否存在。返回 -1 ,表示不存在;返回 0 ,则存在。
4、fill :将list集合所有元素替换成指定元素。
fill练习:
package fuxi1; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 需求:利用集合框架工具类的fill方法给集合中部分元素替换成指定元素。 * 思路:利用List集合subList方法,查询集合部分元素并替换。 *@author XiaLei */ public class Day17Test2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("fdsa"); list.add("fda"); list.add("s"); list.add("ss"); list.add("adfss"); // Collections.fill(list, "hah"); // System.out.println(list); myFill(list,1,2);//改变部分元素。 System.out.println(list); Collections.replaceAll(list, "s", "x");//替换 System.out.println(list); Collections.reverse(list);//反转 System.out.println(list); } public static List<String> myFill(List<String> list,int start,int end){ List<String> list1 =list.subList(start, end); Collections.fill(list1, "haha"); return list; } }
打印结果:
5、reverseOrder :强行逆转比较器。
demo:
package fuxi1; import java.util.Collections; import java.util.Iterator; import java.util.TreeSet; /** * *@author XiaLei */ public class Day17Test3 { public static void main(String[] args) { TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenthCom()));//强行逆转比较器,可以实现自然排序的反转,也可以实现自定义比较器的反转。 //这种功能一定要记住~ ts.add("aaaa"); ts.add("bb"); ts.add("c"); ts.add("dxaio"); for (Iterator<String> it = ts.iterator(); it.hasNext();){ System.out.println(it.next()); } } } /*之前定义过的比较器,拿来演示 class StrLenthCom implements Comparator<String>{ public int compare(String s1,String s2){ if(s1.length()>s2.length()) return 1; if(s1.length()<s2.length()) return -1; else return s1.compareTo(s2); } } */
6、shuffle :随机排序。
7、swap :交换位置。
demo:
package fuxi1; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * *@author XiaLei */ public class Day17Test4 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("fdsa"); list.add("fda"); list.add("s"); list.add("ss"); list.add("adfss"); Collections.swap(list, 1, 4);//换位。 System.out.println(list); Collections.shuffle(list);//随机排序。 System.out.println(list); } }
二、Arrays
Arrays是用于操作数组的工具类。
1)将数组转换为集合
注意:
a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。
b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
好处:可以使用集合的思想和方法来操作数组中的元素。
2)集合变数组
指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。
好处: 可以限定对元素的操作,不可以进行增删了。
第三部分 JDK 1.5的新特性
一、静态导入
1、当类名重名时。需要指定具体的包名
2、当方法重名时。指定具备所属的对象或者类。
二、方法的可变参数
1) 使用注意:可变参数,一定要定义在参数列表的后面。
2) 可变参数传递的使用方式:其实就是上一种数组的参数简写形式,不用每次都动手的建立数组对象,只要将操作的元素作为参数传递即可,隐式的将这些参数封装成了数组。
3) 可变参数的写法:public static void show2(String s,int…arr){}
三、高级 for 循环
1)格式:
for(数据类型 变量名:被遍历的集合(collection) 或者数组){
}
2)for 对集合的遍历,只能获取元素,但是不能对集合进行操作。迭代器除了对集合进行遍历,还能进行 remove 集合中元素的动作。如果是用 ListIterator,还可以在遍历过程中对集合进行增删改查的动作。
3)高级 for 循环的局限性:高级 for 有一个局限性,必须有被遍历的目标。
4)建议:在遍历数组的时候,还是希望使用传统的 for ,因为传统 for 可以定义脚标。高级for:只能对集合中的数据取出,不能做到修改集合中的元素,即使是赋值也没办法。
Demo:
package fuxi1; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * 演示高级for循环。 * 反思:事实上在写博客的时候,我已经是在复习了。高级for也已经用过很多次了,然而在前面的复习中,尤其是集合框架这章, * 用了很多的迭代器进行打印,完全忘了用高级for循环,这就说明了之前学习的不认真,希望自己能够更加努力! *@author XiaLei */ public class Day17Test5 { public static void main(String[] args) { TreeMap<Integer,String> tm = new TreeMap<Integer,String>(); tm.put(1, "java01"); tm.put(2, "java02"); tm.put(3, "java03"); tm.put(4, "java04"); //KaySet方式的高级for循环 Set<Integer> s = tm.keySet(); for(Integer i : s){ System.out.println(i+":"+tm.get(i)); } //entrySet方式的高级for循环 for(Map.Entry<Integer,String> me : tm.entrySet()){ System.out.println(me.getKey()+"="+me.getValue()); } } }
四、JDK 1.5 自动装箱与拆箱
1)Integer i = 5;//自动装箱new Integer(5);
2)i = i+2; //i进行自动拆箱,变成了 int 类型,再和 2 相加,再进行装箱赋值给 i 。
3)byte范围是-128~127之间,所以Integer m,n = 128;已经超出byte范围,所以虽然看似相同,其实他们指向了两个不同的 Integer 对象。
总结
本章知识比较零碎,很多内容容易忽视,比如Collections里的reverseOrder强行逆转比较器方法,这些内容方法都是非常实用的方法,掌握它们有时候会让代码精简很多。所以任何的知识点都要引起重视,一次记不住争取第二次就能记住。
相关文章推荐
- 浅谈Java多线程中的Thread.sleep()和wait()方法的区别
- java实现上传和下载工具类
- Ubuntu12.04 install JDK 1.8.0_05
- Java远程调用邮件服务器,实现邮件发送
- C# MD5 与 java MD5 生成的字符串不一致问题
- 【SpringMVC架构】SpringMVC介绍(一)
- 【SpringMVC架构】SpringMVC介绍(一)
- java中的并发:进程和线程
- 项目实录之集成Mybatis
- 项目实录之Shiro的使用
- java日志组件介绍(common-logging,log4j,slf4j,logback )
- java中的并发:进程和线程
- java web 资源地址写法
- eclipse的使用-------Text File Encoding没有GBK选项的设置
- struts.xml的结构
- Java多线程实现生产者消费者模式
- 如何在ubuntu下安装Java并使用(亲自试过,值得信赖)
- Spring源码阅读-番外一:泛型
- struts2的相关练习
- Intellij1.4入门使用(图片创建javaEE工程)