文章目录

  • 1.Date类:getTime(),SimpleDateFormat
  • 2.Calendar类:只有子类对象才能向上转型
  • 3.System类:System.exit(0)
  • 4.Math类:ceil
  • 5.基本类型包装类:工具类,Integer.parseInt(str),缓存池,深浅拷贝
  • 6.集合:单/双例,Arrays.toString(array)
  • 7.泛型:类/接口/方法,运行看右边
  • 8.泛型通配符:Fu,Zi,Sun是类/数据类型,extends
  • 9.练习:map.keySet(),map.values(),map.entrySet()
  • 10.内部类:.class文件,局部内部类(定义在一个方法里的类,只能当前方法内使用,其他方法不能使用)
  • 11.匿名内部类:=接口实现类,打印对象
  • 12.练习:接口的匿名内部类,没有子类名

1.Date类:getTime(),SimpleDateFormat

package com.itheima02.date;
import java.util.Date;
/*
*   Date: 日期: 构造方法
*       1. Date() : 获取电脑系统当前时间
*       2. Date(long time) : 时间原点 + time (毫秒)
*          时间原点: 1970年1月1号 0时0分0秒 (unix 操作系统)(0经度线)
*          地理: 东八区 + 8个小时
*          普通方法:long getTime(); 获取当前时间-时间原点 (毫秒值)
*/
public class DateDemo {public static void main(String[] args) {Date date = new Date();//引用类型直接打印,理论打印地址值,但重写toString方法如上System.out.println(date); //Fri Sep 25 21:06:39 CST 2020//new Date(0) //Thu Jan 01 08:00:00 CST 1970 默认已经加了8小时  Date date1 = new Date(-1000); System.out.println(date1); //Thu Jan 01 07:59:59 CST 1970 long time = date.getTime();System.out.println(time); //156.....秒System.out.println(time/1000/3600/24/365); //49年}                          //秒  小时  天  年
}
package com.itheima02.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
*   DateFormat : 日期格式化
*       1. 子类
*       SimpleDateFormat(String pattern) : 用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。模式字母: 让SimpleDateFormat知道 日期里的每个时间字段应该填充到模板哪个位置:y,M,d(个数不重要,自动填充)...2. 方法1. String format(Date date)  : 将一个 Date 格式化为日期/时间字符串。2. Date parse(String source)  : 从给定字符串的开始解析文本,以生成一个日期(上面的反向方法)
*/
public class DateFormatDemo {public static void main(String[] args) throws ParseException {Date date = new Date();System.out.println(date); //Fri Sep 25 21:15:31 CST 2020SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");String format = sdf.format(date); System.out.println(format); //2020年09月25日 21时15分31秒String  msg = "1995-02-25";SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");Date parse = sdf2.parse(msg);System.out.println(parse); // Sat Feb 25 00:00:00 CST 1995}
}
package com.itheima02.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
// 案例: 你活了多少天?公式: 当前时间 - 你出生时间  (转换成毫秒)
public class LiveDemo {public static void main(String[] args) throws ParseException {// 1. 当前时间Date date = new Date();long currentTime = date.getTime();// 2. 出生日期System.out.println("请输入你的生日(yyyy-MM-dd)");Scanner sc = new Scanner(System.in);String timeStr = sc.nextLine();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date birthDate = sdf.parse(timeStr);//将字符串转换成Datelong birthTime = birthDate.getTime();long liveDay = (currentTime - birthTime) / 1000 / 3600 / 24;System.out.println("恭喜你,活了" + liveDay + "天了");}
}

2.Calendar类:只有子类对象才能向上转型

package com.itheima02.date;
import java.util.Calendar;
import java.util.Date;
/*
*   Calendar: 日历类(取代Date类)是抽象类,不能实例化
*       1. static Calendar getInstance()使用默认时区和语言环境获得一个日历。(包含系统当前时间),是复杂版的new Date()GregorianCalendar  格里高利历 (公历):  欧洲 罗马历(儒略历)。日本有自己历法问题: 直接去创建 GregorianCalendar子类 , 这个日历不适用日本这样的国家,代码不够国际化2. 方法1. int get(int field) :返回给定日历字段/属性field的值。2. void set(int field, int value) :将给定的日历字段设置为给定值。3. void add(int field, int amount) :根据日历的规则,为给定的日历字段添加或减去指定的时间量。4. Date getTime() :返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象
*/
public class CalendarDemo {public static void main(String[] args) {//        method01();
//        get();
//        set();//.getInstance()是一个静态方法,源码里面肯定创建了子类对象//为什么这样设计?以前直接new子类对象,因为兼容日本等国Calendar c = Calendar.getInstance(); //这一行代码在中国电脑跑公历,在日本跑日本历System.out.println(c); //一大段字母:java.util.GregorianCalendar[...]    c.add(Calendar.DAY_OF_MONTH,-30); System.out.println(c);  //一大段字母:java.util.GregorianCalendar[...] Date time = c.getTime(); //将日历转换为DateSystem.out.println(time); //Wed Aug 26 21:31:24 CST 2020}    private static void set() {//重置时间: 2008-08-08Calendar c = Calendar.getInstance();c.set(Calendar.YEAR,2008);c.set(Calendar.MONTH,7);c.set(Calendar.DAY_OF_MONTH,8);System.out.println(c);}    private static void get() {Calendar c = Calendar.getInstance();int year = c.get(Calendar.YEAR); //2019,静态属性可用类名.调用
//        int year = c.get(1); //2019int month = c.get(Calendar.MONTH) + 1; //9 //几月int day = c.get(Calendar.DAY_OF_MONTH); //7 //几号System.out.println(year + "-" + month + "-" + day);}  private static void method01() {//Calendar c = Calendar子类对象 (向上转型)Calendar c = Calendar.getInstance();System.out.println(c);}
}

3.System类:System.exit(0)

package com.itheima03.system;
/*
*   System : 系统类很重要不让随便修改,java.lang.System。
*      1. System类用final修饰不能被继承【final修饰的类不能被继承但能new,如String】。
*      2. 因为构造方法是private,所以不能实例化。
*      3. 属性和方法全静态(灰色方片),外部才能访问
*/
public class SystemDemo {public static void main(String[] args) { /* String s = new String("abc"); //一般String s = "abc"String uc = s.toUpperCase();int length = uc.length();System.out.println(length);*/ //打印出3        //链式编程: 某个环节的属性和方法是属于谁的, 只要看上一个环节方法返回值和属性类型int length = new String("abc").toUpperCase().length(); System.out.println(length); //3String xx = Person.name;Person.name.length(); //.length()看name类型是string就不报错System.out.println(xx.length()); //3System.out.println(Person.name.length()); //3/** System : 类* out : 静态属性(因为类名.调用)* println() : 属于out的方法(out是PrintStream类型)* out方法定义在System.java中,println方法定义在PrintStream.java中*/System.out.println("abc");}
}
class Person{static String name = "abc";
}
package com.itheima03.system;
import java.util.Arrays;
import java.util.Date;
/*
*   System类方法:1. static long currentTimeMills(); 获取系统当前时间毫秒值
*                2. exit(0); 退出JVM,意味着程序中止运行 (0表示正常退出, 非0异常退出)
*               3. arrayCopy() : 将A数组的元素赋值到B数组,源码里才会看到
*/
public class SystemDemo2 {public static void main(String[] args) {// method01();/* System.arraycopy看源码,参数如下* @param      src     the source array.  源数组* @param      srcPos   starting position in the source array. 源数组的开始位置* @param      dest     the destination array.  目标数组* @param      destPos  starting position in the destination data. 目标数组的开始位置* @param      length   the number of array elements to be copied. 将要被拷贝的数组元素个数* 数组: 长度不可变* ArrayList : 底层是数组, 但长度可变。因为底层原理和arraycopy方法有关*/int[] src = {1,2,3,4,5};int[] dest = {6,7,8,9,0};System.arraycopy(src,2,dest,0,3);String str = Arrays.toString(dest); //[6,7,8,9,0]System.out.println(str);//[3,4,5,9,0]}private static void method01() {long time = System.currentTimeMillis(); //节省内存:少创建new对象System.out.println(time);//150000...long time1 = new Date().getTime();System.out.println(time1);//同上while(true){System.out.println("xx");System.exit(0); //终止死循环}}
}

4.Math类:ceil

package com.itheima04.math;
/*
//Math类 里面方法基本是静态的。方法涉及两数相加并且和对象里所有属性没有关联,可以把这方法设计为静态方法,用类名调用方便,不用创建无用对象浪费内存1. public static int   abs(int a)  返回参数的绝对值  (absolute)                    2. public static double ceil(double a) 返回大于或等于参数的最小double值,等于一个整数天花板 向上取整3. public static double floor(double a) 返回小于或等于参数的最大double值,等于一个整数地板  向下取整4. public   static int round(float a) 按照四舍五入返回最接近参数的int5. public static int   max(int a,int b)  返回两个int值中的较大值6. public   static int min(int a,int b)  返回两个int值中的较小值7. public   static double pow (double a,double b) 返回a的b次幂的值。a底数 b是指数8. public   static double random() 返回值为double的正值,[0.0,1.0) 伪随机数
*/
public class MathDemo {public static void main(String[] args) {int abs = Math.abs(0);System.out.println(abs); //0double d = 1.51; long round = Math.round(d); //四舍五入,底层取余数System.out.println(round); // 2double d2 = -2.1;double ceil = Math.ceil(d2); //向上取整,底层取余再+0.5再四舍五入System.out.println(ceil); // -2.0double floor = Math.floor(d2); //向下取整System.out.println(floor); // -3.0int a = 2;int b = 3;int max = Math.max(a, b);// 底层return a > b ? a : b;System.out.println(max); //3int min = Math.min(a, b);System.out.println(min); //2double pow = Math.pow(2, 10);System.out.println(pow); //1024double random = Math.random();System.out.println(random); // 0-1之间}
}

5.基本类型包装类:工具类,Integer.parseInt(str),缓存池,深浅拷贝

package com.itheima00.question;
/*I love javame 2
*/
public class ToStringTest {static int i = 1;public static void main(String args[]) {System.out.println("love " + new ToStringTest());                // string + object.toString() = string //解释上行,先走toString()打印出"I" //终极规则:string + object = string//  love + java  //因为new ToStringTest()返回toString()(下面有写)即"java "ToStringTest a = new ToStringTest();a.i++; // 2 (静态变量i被该类所有对象所共享)System.out.println("me " + ToStringTest.i); //类名.i}   public String toString() {System.out.print("I ");return "java ";}
}

如下三个工具类有个特点即方法都静态。

package com.itheima01.pack;
import java.util.Scanner;
/*场景: 控制台/网页 输入的所有内容 对java程序都是字符串面向对象: 解决问题,找到对象,然后调用方法来解决问题我/猫  打开  门打开行为 属于 门*   基本类型包装类
*       1. 需求: 类型转换 : String - > int
*       2. 问题: int 基本类型 (没有属性和方法即没有打开行为),预定义在jvm虚拟机中,连包都没有
*       3. Integer 引用类型,这样可以面向对象设置一些方法parseInt(),将类型转换方法设置到Integer中
*
*      基本: byte short int       long float double  char     boolean
*      引用: Byte Short Integer   Long Float Double Character  Boolean (只有int,char不对应)
*      目的: 提供 string 转化成相应基本类型的方法。Integer:static int parseInt(String str) : 将字符串解析成int
*/
public class PackDemo {public static void main(String[] args) {// method01();String str = "100";int count = Integer.parseInt(str);//Integer是类即引用类型,parseInt静态方法,参数是字符串,返回int// long l = Long.parseLong(str); // parse解析System.out.println(count + 1); //101}private static void method01() {System.out.println("请输入你的余额:");Scanner sc = new Scanner(System.in);
//    String str = sc.next();
//    int s = Integer.parseInt(str); //String->int ,别的类型转为我自己int类型,方法设在int上int s = sc.nextInt(); //nextInt()底层就是上面两行System.out.println(s + 1);//101}
}
package com.itheima01.pack;
/*
*   JDK1.5特性: 自动拆箱 : 在运算过程, Integer -> int
*               自动装箱 : 在赋值过程, int -> Integer
*/
public class PackDemo02 {public static void main(String[] args) {//        method01();Integer i1 = new Integer(200);Integer i2 = new Integer(200);System.out.println(i1 == i2);//false  new出来:比的是地址System.out.println(i1.equals(i2)); //true,Integer重写了equalsInteger i3 = 200; // 自动装箱 int ->Integer(Integer是引用数据类型有地址)Integer i4 = 200; // 同上,这样i4可以调用toString,compareTo,intValue(很少用,用自动拆箱)等方法System.out.println(i3 == i4); //falseSystem.out.println(i3.equals(i4)); //true /**   Integer内部缓存池: cache*           -128 ~ 127(byte取值范围) 最常用(6种数据类型都包含这范围)*      1. 如果创建一个Integer对象,那么先去缓存池中看看,有没有这个对象*      2. 如果没有,就创建这个对象。如果有, 就直接返回这个对象*/Integer i5 = 100; // 0x0001 缓存池Integer i6 = 100; // 0x0001,i6.valueof点进源码可看见  System.out.println(i5 == i6);//true  i5和i6的地址是一样System.out.println(i5.equals(i6));//true}private static void method01() {//Integer i = new Integer(200); //Integer作为一个引用类型应该要去newInteger i = 200;// 自动装箱,等于上行,200基本类型自动变为对象即引用类型int y = i + 1; // 自动拆箱System.out.println(y);//201}
}

Integer i = 10;  //装箱
int n = i;   //拆箱

// return在无返回值方法的特殊使用
public void f5(int a) {if (a > 10) {return;//表示结束所在方法 (f5方法)的执行,下方的输出语句不会执行}System.out.println(a);
}

6.集合:单/双例,Arrays.toString(array)

package com.itheima02.container;
import java.util.ArrayList;
// java容器:1. 数组  2. 集合(变,只对,不)
public class ContainerDemo {public static void main(String[] args) {int[] array = {1,2,3};Person[] array2 = {new Person(),new Person()};String[] array3 = {"abc","bcd"};Object[] array4 = {"abc",new Person()}; //多态: 向上转型,都转为Object类型ArrayList<Integer> list = new ArrayList<>(); //ArrayList<Integer>泛型里不可写<int>基本数据类型list.add(1);list.add(2); // 自动装箱成引用数据类型}
}
class Person{}


package com.itheima03.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
/*collection(东西收集在一起就是集合)常用方法 (不带索引),以下方法是所有集合都具备1. add1. 添加元素,返回值boolean,成功为true2. list中元素可重复,故恒为true。set中元素不可重复,有可能为false2. clear1. 清空集合中的所有元素。集合容器本身不会改变,继续使用3. remove1. 移除集合中的单个实例(参数obj),移除成功返回true4. isEmpty1. 判断当前集合的元素个数是否为05. contains1. 包含某个元素,如果有返回true,区分大小写6. size1. 获取大小7. toArray1. 集合中的元素,变成数组。集合存储的数据类型不确定,返回的数组只能是Object
*/
public class CollectionDemo {public static void main(String[] args) {// method01();  //如下把Collection改为ArrayList,则coll.set就会有ArrayList特有的方法,Collection没有Collection<String> coll = new ArrayList<>();//Collection是接口,不能实例化,所以只能创建子类对象coll.add("张三");coll.add("李四");coll.add("王五");//将集合中所有的元素放到数组中,数组有索引Object[] objects = coll.toArray();for (int i = 0; i < objects.length; i++) {Object element = objects[i];System.out.println(element);}}private static void method01() {//如下行编译看左边: 父类无法调用子类特有的方法(可调用子类重写的方法)。所以把学习的方法限制于Collection集合内,不会用到ArrayList特有的方法Collection<String> coll = new ArrayList<>(); //ArrayList改为HashSet,则若加add两个张三则报错coll.add("张三");coll.add("李四");coll.add("王五");boolean result = coll.add("马六"); //添加成功返回true,失败为false(基本没用)System.out.println(result);System.out.println(coll);//[张三,李四...]引用类型打印不是内存地址必然重写了toString方法//coll.clear(); //清空集合中所有的元素//System.out.println(coll); //[] 空篮子//System.out.println(coll == null); // false 篮子还在boolean result2 = coll.remove("马六"); //移除成功返回true(基本没用)System.out.println(result2);System.out.println(coll);System.out.println(coll.size()); // 3System.out.println(coll.isEmpty()); //false//如果集合中包含某个元素,就返回trueboolean result3 = coll.contains("李四");System.out.println(result3);}
}

hasNext()返回true就调用next(),迭代器不断运行直到返回false。

package com.itheima04.iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
*   遍历: 全部经历
*   迭代: 相同的动作不断执行。版本迭代:开发 -> 测试 -> 上线 1.0。开发 -> 测试 -> 上线 2.0 ...
*
*   迭代器 : 不断循环的机器  iterator
*       1. boolean hasNext(); 判断是否有下一个元素,如果有,就返回true
*       2. 元素 next();  向后移动一位,并获取当前元素
*
*   Collection方法,如下E是泛型返回值
*       Iterator<E> iterator() : 返回在此collection的元素上进行迭代的迭代器。
*   以前for循环基于索引,Collection没有索引,但有迭代器好用
*/
public class IteratorDemo {public static void main(String[] args) {//        method01();Collection<String> coll = new ArrayList<>();coll.add("张三");coll.add("李四");coll.add("王五");Iterator<String> it = coll.iterator();while(it.hasNext()){ //while取代下面的几次if循环String name = it.next();System.out.println(name);}}private static void method01() {Collection<String> coll = new ArrayList<>();coll.add("张三");coll.add("李四");coll.add("王五");//获取collection集合的迭代器(相当于指针)Iterator<String> it = coll.iterator();//第一次迭代if (it.hasNext()){String name = it.next(); System.out.println(name); //张三}//第二次迭代if (it.hasNext()){String name = it.next(); System.out.println(name);//李四}//第三次迭代if (it.hasNext()){String name = it.next();System.out.println(name); //王五}//第四次迭代,it.hasNext()返回falseif (it.hasNext()){String name = it.next();System.out.println(name);}}
}

s1地址先赋给s2,s2地址后又改变了。

package com.itheima05.foreach;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
/*
*   增强for循环:
*       1. 前置
*           1. 普通for循环 : fori快捷键
*                for (int i = 0; i < 10; i++) {list.set(i,"马六"); //可以修改}2. 语法糖(syntax sugar) : 原理相同,但是更为简练的语法2. for...each 快捷键array.for1. 集合 : 作为迭代器的语法糖collecition支持增强for循环语法:for(元素类型 变量名 : 被遍历的集合){}代价: 只适合用来查 (不适合用来修改集合内容)2. 数组 : 作为普通for循环的语法糖
*/
public class ForeachDemo {public static void main(String[] args) {// method01();int[] array = {1, 2, 3};/* for (int i = 0; i < array.length; i++) {int element = array[i];element = 10;System.out.println(element); //10array[i] = 10;System.out.println(array.toString()); //[I@14ae5a5System.out.println(Arrays.toString(array)); // [10, 2, 3],[10, 10, 3],[10, 10, 10]}System.out.println(Arrays.toString(array)); //[10, 10, 10] */for (int element : array) {        //1System.out.println(element);   //2}                                  //3                                           System.out.println(Arrays.toString(array)); //[1,2,3]}private static void method01() {Collection<String> coll = new ArrayList<>();coll.add("张三");coll.add("李四");coll.add("王五");
/*      Iterator<String> it = coll.iterator();while(it.hasNext()){String name = it.next(); //这行相当于get方法name = "马六";System.out.println(name); //马六 马六 马六}System.out.println(coll); //依然还是[张三,李四,王五] */ //下面代码称为上面代码语法糖,匿名内部类也是语法糖,将定义类和创建对象合二为一。for(String name : coll){ //name会被coll里面的每一个元素循环赋值//System.out.println(name);name = "马六";}System.out.println(coll); //依然还是[张三,李四,王五]}
}

7.泛型:类/接口/方法,运行看右边


如下不用泛型。

如下没有泛型存在安全问题,泛型就和overwrite注解一样,要不要无所谓,要就检查。

/*
*   1. 为什么要使用泛型?
*       1. 一般的需求, 一个集合都是用来同一种类型的数据 , 早期是没有泛型的, 意味着集合可以存任意引用类型
*       2. 这样就带来一个问题: 但凡需要用来子类特有方法, 集合类型为Object,都需要向下转型(强转)
*           -> 风险: 类型转换异常 (运行的时候)
*       3. 泛型: 给集合设置泛型, 那么这个集合就会在编译时候发现运行时期才发现的问题
*           先编译 后运行。泛型: 安全预警机制, 不是强制使用, 一般都会用
*
*   2. java里的泛型 是 伪泛型 :java泛型只存在编译时期(泛型擦除), 不存在运行时期
*/


如下ArrayList < Object > 类型是ArrayList < String > 的父类吗?不是,因为放动物(Object)笼子不能说是放狗(String)笼子的爸爸,本质都是笼子(ArrayList),但可以说动物是狗的父类。

package com.itheima06.generic;
import java.util.ArrayList;public class GenericClassDemo {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(100); Integer integer = list.get(0); //0为int index        //如上add,get只能是Integer,原因如下://对mc来说, 在创建对象时, T=StringMyClass<String> mc = new MyClass<>();mc.add("abc");    //对mc2来说, 在创建对象时, T=IntegerMyClass<Integer> mc2 = new MyClass<>();mc2.add(1);}
}
/*
*   泛型类: 1. class 类名<泛型变量>{ }
*           泛型变量 一般为单个大写字母
*         2. 泛型T 变量 , 只能赋值引用类型 String,Integer...
*         3. 创建对象的时候,对T 进行赋值
*         4. 某个泛型类对象 T赋值为String,那么这个对象中所有的T=String
*/
class MyClass<T>{ public void add(T str){ //str随便写 }
}
package com.itheima06.generic;
import java.util.ArrayList;
import java.util.Properties;
/*
*   泛型接口: interface 接口名<泛型变量>{  }
*   类实现泛型接口:1.继续向下传递泛型  2.直接对泛型进行赋值,不再向下传递
*/
public class GenericInterfaceDemo {public static void main(String[] args) {new Properties(); //ctrl+左键进去看源码 //Properties类是Properties文件和程序的中间桥梁,不论是从properties文件读信息还是写信息到properties文件都要经由Properties类}
}
interface MyInter<Q>{void add(Q q);
}
class MyClass01<Q> implements MyInter<Q>{ //继续向下传递泛型 //eg: ArrayList类@Overridepublic void add(Q q) { //一个类实现接口必须重新给方法}
}
class MyClass02 implements MyInter<String>{ //Q赋值为String //eg: Property类@Overridepublic void add(String s) {}
}
package com.itheima06.generic;
import java.util.ArrayList;
/*
*   泛型方法: 修饰符  <泛型变量> 返回值 方法名(参数列表){
*             }
*            1. 泛型变量在调用此方法的时候进行赋值
*            2. 泛型变量只可本方法内部
*   需求: 请你设计一个方法 既能接收list1,又能接收list2
*/
public class GenericMethodDemo {public static void main(String[] args) {ArrayList<String> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();MyClass03.method00(list1); // P = StringMyClass03.method00(list2); // P = Integer}
}
class MyClass03{public static <P>void method00(ArrayList<P> list){ //写成ArrayList<Object> list不行,蓝子间没继承关系。//ArrayList<Object>类型不是ArrayList<Integer>类型的父类,运行擦除泛型可以通过但在编译一开始就不能通过。}
}

8.泛型通配符:Fu,Zi,Sun是类/数据类型,extends

如下区分biglist和list。由于addAll(object类型的list),list是object,导致Fu fu报红。但不应该为Fu fu报红,应该addAll(list)报红,所以红色横线用泛型通配符


package com.itheima06.generic;
import java.util.ArrayList;
/*
*   泛型通配符 : ?(表示一个范围)
*       1. ? extends Fu : Fu及其子类 (上限)
*       2. ? super  XX : XX及其父类 (下限)
*/
public class GenericSymbolDemo {public static void main(String[] args) {ArrayList<Fu> fuList = new ArrayList<>();ArrayList<Zi> ziList = new ArrayList<>();ArrayList<Sun> sunList = new ArrayList<>();ArrayList<Object> objList = new ArrayList<>();addAll(fuList);addAll(ziList);addAll(sunList);//addAll(objList); //编译不通过,放不进}/**   方法: 内部有个内部有个bigList, 想要把参数(集合)中的所有元素都吸纳*           内部有个bigList  :  ArrayList<Fu> : 吸纳 : Fu 及其子类 的元素类型集合*/private static void addAll(ArrayList<? extends Fu> list) {ArrayList<Fu> bigList = new ArrayList<>();
//        bigList.add(new Fu());
//        bigList.add(new Zi()); //向上转型
//        bigList.add(new Sun()); //向上转型for (Fu fu : list) {bigList.add(fu);}}
}
class Fu{}
class Zi extends Fu{}
class Sun extends Zi{}

9.练习:map.keySet(),map.values(),map.entrySet()

public class TestGeneric {   @Testpublic void test1(){      ArrayList list = new ArrayList();  //存本组学员的姓名,String对象list.add("张三");list.add("李四");list.add("王五");list.add(1);       for (Object object : list) { //使用时,不知道我这里面是String类型,统统按照Object//每次使用元素时,可能需要强转,很麻烦,好比每次打开瓶子,你需要闻一下String name = (String) object;//强转有风险System.out.println("名字的长度:" + name.length());}}
}
package com.atguigu.test02;
import java.util.ArrayList;
import org.junit.Test;
//泛型的好处:(1)安全(2)避免类型转换
public class TestGood {@Testpublic void test1(){ArrayList<String> list = new ArrayList<String>();list.add("张三");list.add("李四");list.add("王五");
//      list.add(1);//编译报错,因为我告诉ArrayList,我的元素类型是String,所以Integer对象进不去     //此时不需要用Object处理了,因为它知道里面的元素是Stringfor (String name : list) {System.out.println("名字的字数:" +name.length());}}
}
package com.atguigu.test03;
import java.util.ArrayList;
import java.util.Iterator;
//把本组学员的姓名,存储到ArrayList集合中,并且指定泛型,并且要使用foreach和Iterator分别迭代,也要正确指定泛型
public class TestExer1 {public static void main(String[] args) {        ArrayList<String> list = new ArrayList<String>(); //姓名,泛型指定为String  list.add("杨洪强");list.add("苏海波");list.add("甄玉禄");System.out.println("foreach迭代");for (String name : list) {System.out.println(name);}System.out.println("Iterator迭代");     //Iterator<E>这个E代表你要迭代的集合的元素类型Iterator<String> iterator = list.iterator();while(iterator.hasNext()){String name = iterator.next();System.out.println(name);}}
}

package com.atguigu.test03;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
/** 把本组学员的组长姓名作为key,组员的姓名作为value,多个组员用ArrayList装起来,
放到HashMap中,正确指定泛型,并且遍历。当如果出现泛型的嵌套,那么从外到内分析*/
public class TestExer2 {public static void main(String[] args) {//HashMap<K,V>:K代表key的类型,V代表value的类型
//组长姓名作为key,说明K是String。组员的姓名作为value,多个组员用ArrayList装起来,说明V是ArrayList类型
//因为ArrayList也是泛型类,ArrayList中装的是组员的姓名,所以是String类型HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();  ArrayList<String> group1 = new ArrayList<String>();group1.add("杨洪强");group1.add("苏海波");        map.put("杨洪强", group1); //组长:杨洪强ArrayList<String> group8 = new ArrayList<String>();group8.add("崔志恒");group8.add("甄玉禄");group8.add("杜冠军");      map.put("崔志恒", group8); //组长:崔志恒System.out.println("遍历所有的组长:");Set<String> keySet = map.keySet();for (String zuZhang : keySet) {System.out.println(zuZhang);}System.out.println("遍历所有的学员:");Collection<ArrayList<String>> values = map.values();for (ArrayList<String> group : values) {System.out.println(group);}System.out.println("遍历每一组的情况:");Set<Entry<String, ArrayList<String>>> entrySet = map.entrySet();for (Entry<String, ArrayList<String>> entry : entrySet) {System.out.println(entry);}}
}

10.内部类:.class文件,局部内部类(定义在一个方法里的类,只能当前方法内使用,其他方法不能使用)

package com.itheima05.innerclass;
/*
*   1. 定义在一个类A内部的另外一个类B, 那么A称之为外部类, B称之为内部类
*        内部类: 访问受限(要通过外部来访问内部)
*
*   2. 成员内部类: 定义一个类成员位置的类 (少见)
*        1. 语法:外部类名.内部类名(声明) 变量名 = 外部类对象.new 内部类();
*        2. 编译:多了一个:OuterClass$InnerClass.class
*
*   3.
*/
public class InnerDemo { //有.class文件public static void main(String[] args) {class MethodClass{ //定义在main方法里称为局部内部类  int methodField;void method(){}}                   MethodClass mc = new MethodClass(); //上面的类mc.methodField = 1;mc.method();}public static void method01(){OuterClass oc = new OuterClass(); //main方法外面即下面的类oc.outerField = 1;  //属性oc.outerMethod();  //方法OuterClass.InnerClass ic = oc.new InnerClass(); //main方法外面即下面的类ic.innerFiled = 2;ic.innerMethod();         // MethodClass mc = new MethodClass(); //错误,不能访问}
}class OuterClass{ //外部类 //有.class文件int outerField; //成员void outerMethod(){ }    class InnerClass{ //成员内部类 //有.class文件int innerFiled;void innerMethod(){}}
}

11.匿名内部类:=接口实现类,打印对象

package com.itheima05.innerclass;
/*
*     1. 匿名内部类 属于 方法/局部内部类 的一种
*     2. 匿名内部类 没有 类名
*     3. 目的 : 简化代码编写
*         new 父类/父接口() {  //class body 即类体
*              如果有抽象方法,必须重写
*          }
*        创建出来的是父类/父接口的子类对象
*        原理:  定义类+创建对象  合二为一
*/
public class InnerDemo02 {public static void main(String[] args) {Dog twoHa = new Dog(); //Animal twoHa = new Dog();也可以即多态voice(twoHa); //汪汪叫//11111111111111111111111111111111111111111111111111111111111111111111111111111  //InnerDemo02$Wolf.class //第一个内部类有名字Wolf   class Wolf implements Animal{ //以前这类写在main方法外 //定义类@Overridepublic void shout() {System.out.println("嗷嗷叫");}}Wolf greyTai = new Wolf();  //创建对象voice(greyTai); //嗷嗷叫//111111111111111111111111111111111111111111111111111111111111111111111111111111111/** 类名如dog,wolf其实在某些场景下一定都不重要,重要的类体(重写shout方法)* 语法: 多了个类体,但是把类名隐藏掉了叫匿名* 省略: 1. 以前:  定义类  然后 创建对象*       2. 现在: 创建对象+定义类  合二为一*/// Animal a = new Animal(); //接口不能实例化,如下加方法体        // 父接口 变量 = 父接口子类对象 (向上转型)Animal a = new Animal(){ //多了一个大括号,InnerDemo02$1.class 第二个内部类也是第一个匿名内部类用1@Overridepublic void shout() {System.out.println("嘎嘎叫"); }};voice(a); //嘎嘎叫//111111111111111111111111111111111111111111111111111111111111111111111111111111111// InnerDemo02$2.class  //第三个内部类也是第二个匿名内部类用2Animal b = new Dog(){ //这样写也可以,同上@Overridepublic void shout() {System.out.println("呱呱叫");}};b.shout(); // 呱呱叫//1111111111111111111111111111111111111111111111111111111111111111111111111111111//匿名内部类的匿名对象,最简洁  //InnerDemo02$3.classvoice(new Animal() {@Overridepublic void shout() {System.out.println("喵喵叫"); // 喵喵叫}});}      private static void voice(Animal a) { //Animal接口, 接口不能实例化a.shout();}
}//111111111111111111111111111111111111111111111111111111111111111111111111111
interface Animal{ //一般不用abstract Animalvoid shout(); //叫
}
class Dog implements Animal{ //多态要写,匿名内部类不用@Overridepublic void shout() {System.out.println("汪汪叫");}
}


如下这个类对象就用一次,没必要取个名字,如果取名字还要单独的.java文件。

12.练习:接口的匿名内部类,没有子类名

子类特有方法不是子类重写方法,如下2解决。

package com.atguigu.test10;
/*
(1)声明一个抽象类Father,包含抽象方法:public abstract void method();
(2)用匿名内部类继承Father,并重写抽象方法,打印“hello 孩子"。并调用子类对象的method方法
*/
public class TestExer3 {public static void main(String[] args) {/*new Father(){public void method(){System.out.println("hello 孩子");}}.method();*/// 上下一样Father f = new Father(){public void method(){System.out.println("hello 孩子");}};f.method(); //hello 孩子}
}
abstract class Father{public abstract void method();
}

接口、抽象类可理解成是模糊不定的东西,要使用它的特质必须要实例化且实例化不能直接通过new。如下代码不同于普通的实例化对象,而是通过new一个实现接口的匿名内部类Runnable,使用{}具体实现接口。

package com.atguigu.test10;
import java.util.Arrays;
import java.util.Comparator;public class TestExer4 {@SuppressWarnings("all")public static void main(String[] args) {//(2)在测试类中创建Employee数组Employee[] all = new Employee[3];all[0] = new Employee(2, "张三", 10000);all[1] = new Employee(1, "李四", 30000);all[2] = new Employee(3, "王五", 20000);    //(3)分别调用Arrays.sort(数组,Comparator),用匿名内部类实现按照编号升序排列,接口一定要重写方法Arrays.sort(all, new Comparator(){@Overridepublic int compare(Object o1, Object o2) {Employee e1 = (Employee) o1;Employee e2 = (Employee) o2;return e1.getId() - e2.getId();}           });for (int i = 0; i < all.length; i++) {System.out.println(all[i]);}// (4)分别调用Arrays.sort(数组,Comparator),用匿名内部类实现按照薪资升序排列Arrays.sort(all , new Comparator() {@Overridepublic int compare(Object o1, Object o2) {Employee e1 = (Employee) o1;Employee e2 = (Employee) o2;              if(e1.getSalary() > e2.getSalary()){return 1;}else if(e1.getSalary() < e2.getSalary()){return -1;}return 0;}});for (int i = 0; i < all.length; i++) {System.out.println(all[i]);}}
}//(1)声明一个员工类Employee,有属性:编号、姓名、薪资
class Employee{private int id;private String name;private double salary;public Employee(int id, String name, double salary) {super();this.id = id;this.name = name;this.salary = salary;}public Employee() {super();}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}@Overridepublic String toString() {return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";}
}


【Java6】Date类/Calendar类,System类/Math类,包装类,集合,泛型,内部类相关推荐

  1. 常用类(Date,Calendar,SimpleDateFormat,Math,System)

    Date java时间日期的类,基本已经过时了 @Testpublic void test06() {Date date = new Date();//返回当前系统时间date = new Date( ...

  2. java int相除向上取整_java实战项目常用类,Date、Calendar、BigDecimal、Math、UUID

    Java开发中经常用到的类和方法,以下主要就日期是时间处理.金融数字处理.数学计算.随机数.MD5加密等. java.util.Date类 java.util 包提供了 Date 类来封装当前的日期和 ...

  3. java枚举类是什么_Java学习--常用类(2)、Math类、枚举类

    1.日期时间类 小知识:在我们日常生活所使用的计算机端时间,实际上是对某一个特定时间的计数,即我们现在的时间离特定时间的间隔,这个间隔被称之为时间戳(timestamp),这个特定时间是:1970-0 ...

  4. 带有静态方法的类(java中的math类)

    带有静态方法的类通常(虽然不一定是这样)不打算被初始化. 可以用私有构造函数来限制非抽象类被初始化. 例如,java中的math类.它让构造函数标记为私有,所以你无法创建Math的实例.但Math类却 ...

  5. Java学习 day12 (常用API2)Object、Date、DateFormat、Calendar、System、StringBuilder、包装类

    前言: 在java中,API是指一些预先定义的函数,直接导入API就可以快速使用已经编写好的代码和与之对应的功能,之前我们也进行了一些常用API的学习,比如String类.Arrays类.Math类, ...

  6. JAVA常用工具类→Date、SimpleDateFormat、Calendar、System、Math

    JAVA在线JDK https://tool.oschina.net/apidocs/apidoc?api=jdk-zh

  7. 每日加瓦,终成栋房7-Object、Date、DateFormat、Calendar、System、StringBuider、包装类

    一.Object 对象 包名所在地:java.lang.Object 描述:所有类的父类,所有方法的子类都可以使用,再对象实例化的时候,最终的父类就是Object.若一个类没有指向父类,那么就会默认指 ...

  8. Java 日历类 Calendar

    Java 日历类 Calendar 1.java.util.Calendar(日历)类 1.java.util.Calendar(日历)类 Calendar是一个抽象基类,==主要用于完成日期字段之间 ...

  9. 1、Math类的常用方法

    Java 中的 +.-.*./ 和 % 等基本算术运算符不能进行更复杂的数学运算,例如,三角函数.对数运算.指数运算等.于是 Java 提供了 Math 工具类来完成这些复杂的运算. 在 Java 中 ...

  10. 第三次学JAVA再学不好就吃翔(part67)--Math类

    学习笔记,仅供参考,有错必纠 Math类 Math类是在java.lang包下的一个类,我们使用这个类时不需要导包.这个类被final修饰,也就是说,它是最终类,不能被继承.Math 类包含用于执行基 ...

最新文章

  1. 算法-判断一颗树是否是搜索二叉树
  2. 宏EXPORT_SYMBOL在内核中的作用
  3. Tengine的Linux下安装和启动
  4. 震惊!html文件注释也会影响运行代码!(werkzeug.routing.BuildError: Could not build url for endpoint)莫名其妙
  5. UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组、ST表)
  6. Kubernetes 1.6新特性
  7. IE-OLD IE 提示
  8. 突然决定!自掏腰包送Intel酷睿12代CPU!还有机械键盘、固态硬盘。
  9. 博途pcpg接口无法选择_博途TIA功能,如何创建一个S7-1200的项目及硬件组态?
  10. AMD Cubemapgen for physically based rendering
  11. oracle lpad 字符集,oracle Lpad()函数和Rpad()函数的用法
  12. ios标签控制器怎么用_带故事板的iOS标签栏控制器
  13. [CSS3]制作50个超棒动画效果教程
  14. SAP-ABAP学习日常
  15. 计算机科学与技术到底学什么?
  16. P2756 飞行员配对方案问题【二分匹配】【网络流Dinic、EK详解】【萌新初写】
  17. [oeasy]python0020换行字符_feed_line_lf_反斜杠n_B语言_安徒生童话
  18. Zero-Shot Deep Domain Adaptation[reading notes]
  19. 前端3D立体魔方小游戏
  20. pytorch:线性回归实战

热门文章

  1. HDU 1294 Rooted Trees Problem
  2. 蓝桥杯练习(java):字符串对比
  3. python路由编程_Python Django基础二之URL路由系统
  4. ise的时钟ip核_ISE的IP核clocking wizard使用和例化
  5. 每日程序C语言45-连接两个链表
  6. jni加载第三方so_Linux的so文件到底是干嘛的?浅析Linux的动态链接库
  7. 九章算法班L3 Dynamic Programming Ⅰ
  8. 格式化输出,运算符,编码,字符串(索引,切片,大小写转换等等)
  9. Java 接口 新特性(Java8)
  10. osgEarth使用没有DX的Triton库Triton-MT-DLL-NODX.lib