.t1 { background-color: #ff8080; width: 1100px; height: 40px }

 1.成员内部类。

(1)成员内部类的实例化:

外部类名.内部类名   变量名=外部类对象.new 内部类名();

  1. class Person{
  2. class Test{
  3. }
  4. }
  5. Person p=new Person();
  6. Person.Test t=p.new Test();

(2)在内部类中访问外部类属性或方法。

  外部类名.this.属性名
   Person.this.name
(3)成员内部类声明的注意事项
  ①内部类不能与外部类重名。
  ②成员内部类中不能出现静态属性,静态方法和静态内部类。
     但是静态常量例外。
 private static final String name=”1″;//此情况可以使用

  1. class Test{//成员内部类
  2. private String name;
  3. private int age;
  4. public void say(){
  5. System.out.println(Person.this.name);//访问外部类的
  6. System.out.println("Person中的Test的say方法");
  7. }
  8. }

2.静态内部类。

(1)使用static修饰的内部类,叫做静态内部类。

(2)实例化:外部类名.内部名 变量=new 外部类名.内部类名();

  1. class Person{
  2. public String name="1";
  3. public Static int age="12";
  4. static class Test{
  5. }
  6. }
  7. Person.Test t=new Person.Test();

   注意与成员内部类实例化的区别。

(3)静态内部类中不能访问外部类的非静态属性和方法。

   但可以访问外部类中的静态属性和方法,使用外部类名.属性名;
     Person.age;

(4)外部类不能访问静态内部类的非静态属性和方法,但可以访问静态内部类的的静态属性和方法,外部类名.属性名。

    Test.age;

(5)【静态内部类和成员内部类的区别】

  1.声明方式和实例化方式不同。成员内部类不带static
     静态内部类实例化: Person.Test t=new Person.Test();
     成员内部类实例化: Person.Test t=p.new Test();
  2.成员内部类中不能出现静态属性和方法,但静态内部类可以。
  3.外部类和内部类的互相访问权限不同:
    ①静态内部类中不能访问外部类的非静态属性和方法。
    但可以访问外部类中的静态属性和方法,使用外部类名.属性名;
    ②成员内部类中不能出现静态属性,静态方法和静态内部类。
    但是静态常量例外。

  1. static class Test1{
  2. public static String test="111";
  3. public void say(){
  4. System.out.println("Test1");
  5. }
  6. }

3.【局部内部类】(一般不用)。

(1)定义在某个类中的方法中的内部类,称为局部内部类。
(2)局部内部类是对外部完全隐藏的,只能在其作用域范围内被实例化。
(3)局部内部类可以访问外部类的属性和方法,使用外部类.this.属性名;
  Person.this.name;
(4)局部内部类:不能访问其所在方法中的变量,只能访问常量。
(5)注意:局部内部类不能使用访问修饰符修饰,因为它不属于类的成员,它属于方法中的局部变量。

  1. public void eat(){
  2. // final String name1="123";
  3. class Test2{
  4. public String name="123";
  5. public void test(){
  6. System.out.println(Person.this.name);
  7. // System.out.println(name1);
  8. }
  9. }
  10. Test2 t=new Test2();
  11. System.out.println(t.name);
  12. }
  13. }

4.匿名内部类。

new Test1(){

 };
(1)写法
(2)含义:相当于一个匿名类继承了Test1类,使用匿名内部类将直接返回当前子类的对象。
Test1 t=new Test1(){};
(3)相当于:①一个匿名内部类,继承了Test1类。
        ②匿名内部类返回一个子类对象,并付给父类引用。
    因此这一行代码用于向上转型。
(4)匿名内部类通常用于直接实例化抽象类或接口。
  Test1 t=new Test1(){
     //重写抽象类Test1中的所有的抽象方法
    //相当于一个匿名内部类,继承了Test1类,然后返回这个匿名内部类的对象。
};

  1. Test1 t2=new Test1(){
  2. public int age=12;
  3. public void eat(){
  4. System.out.println(age);
  5. System.out.println("eat");
  6. }
  7. public void say(){
  8. System.out.println("匿名重写Test1类的say方法");
  9. }
  10. };
  11. //向上转型,会丢失掉子类特有的属性和方法,new Test1(){}.eat();
  12. t2.say();

5.使用内部类模拟多继承 。

  1. class A{
  2. public void a() {
  3. System.out.println("a");
  4. }
  5. }
  6. class B{
  7. public void b(){
  8. System.out.println("b");
  9. }
  10. }
  11. class C{
  12. class A1 extends A{
  13. }
  14. class B1 extends B{
  15. }
  16. public void a(){
  17. new A1().a();//不管A类是不是抽象类都可以,如果是A则要考虑是不是抽象类
  18. }
  19. public void b(){
  20. new B1().b();
  21. }
  22. }
  1. C c=new C(); //结果a,b
  2. c.a();
  3. c.b();

.t1 { background-color: #ff8080; width: 1100px; height: 40px }

 1.【接口的定义】

(1)接口名/接口文件与类类似,接口也是使用.java文件编写。

(2)声明接口的关键字:interface,接口名命名规范与类名相同,习惯上,接口可以用I开头表示。

(3)接口的访问修饰符只能使用public和default修饰,不能使用protected和private(与外部类相同)。

(4)接口中的所有的属性,只能是公共的,静态的,常量。

   public static final int NAME=1;

  而且,public/static/final都可以省略,省略后依然是公共的,静态的常量。

  int NAME=1;

(5)接口中所有的方法必须是公共的抽象方法。

  而且,接口中的抽象方法,也可以省略public/abstract关键字。

  (public abstract) void say();

 2.【实现类实现接口】

(1)一个类实现接口使用implements关键字

(2)实现类实现一个接口,必须重写接口中的所有抽象方法,除非这个类是抽象类。

   一个类可以使用多个接口,多个接口之间,使用逗号隔开。

   class Desk implements IUsb2,3()

   一个类如果实现多个接口,必须重写所有接口中的所有方法。

(3)接口的引用可指向其实现类的对象(类似于父类引用指向子类对象)

  IUsb2 usb=new UDesk();

  因此可以使用接口实现多态。

 3.【接口继承接口】

(1)接口可以继承接口,使用extends关键字,接口继承与类的接口一样。

interface IUsb3 extends IUsb2{}

(2)接口可以多继承,多个父接口用逗号分隔,子接口继承多个父接口,将拥有所有父接口的抽象方法。

interface IUsb3 extends IUsb2,IUsb1{}

(接口不能被实例化)

4.【接口和抽象类的区别】 

 它们的本质区别:

  抽象类是一个类,接口是一个接口,子类继承抽象类,要求子类必须和父类是同一类事物,必须符合is-a关系。

  接口只是对功能的扩展。

  多个实现类实现接口时,并不要求所有的实现类是一类事物。

  接口符合like-a关系,理解为XXX具备一个XXX功能。比如人类狗类都具有吃饭功能,都具有吃饭接口,但是人类狗类的吃饭功能不能从同一个父类中继承。

(1)抽象类只能单继承,接口可以多继承,多实现。

(2)抽象类可以有自己的属性,接口中只能有静态常量。

(3)抽象类可以有非抽象方法,接口中的所有方法都必须是抽象方法(接口中的抽象方法可以省略abstract )。

(4)抽象类是一个类,接口是一种规范。

  子类继承抽象类,要求子类必须和父类是同一类事物。

  接口并不要求多个实现类是同一类事物,只能进行设计与实现的分离。

  1. interface IUsb2 {
  2. /* public final static*/ int NAME=1;
  3. // public String name="1";//name是静态的,斜体的,接口的静态属性
  4. /*public abstract*/public void useUsb2();//在类中没有大括号必须加abstract修饰
  5. }
  6. interface IUsb3 extends IUsb2{
  7. void useUsb3();
  8. }
  9. class UDesk implements IUsb2,IUsb3{
  10. @Override
  11. public void useUsb2() {
  12. // TODO Auto-generated method stub
  13. System.out.println("U盘使用useUsb2接口读取数据");
  14. }
  15. public void useUsb3() {
  16. // TODO Auto-generated method stub
  17. System.out.println("U盘使用useUsb3接口读取数据");
  18. }
  19. }
  20. class PC{
  21. private IUsb2 usb2 ;
  22. public PC(IUsb2 usb2){
  23. super();
  24. this.usb2=usb2;
  25. }
  26. public void useUsb(){
  27. usb2.useUsb2();
  28. }
  29. }
  30. public class Usb{
  31. public static void main(String[] args) {
  32. // TODO Auto-generated method stub
  33. System.out.println(IUsb2.NAME);
  34. IUsb2 usb=new UDesk();
  35. PC pc=new PC(new UDesk() );
  36. pc.useUsb();
  37. }
  38. }

1.【java的集合框架】
 接口:
          collection                                                       map
      list                      set
 实现类:
 ArrayList              HashSet                                   HashMap
LinkList              LinkHashSet                          LinkHashMap
Vector                   TreeSet                                   TreeMap
                                                                           HashTable

StringBuffer:安全
StringBuild:不安全
ArrayList:线程不安全
Vector:线程安全

2.【四个接口的区别】

(1)Collection:存储不唯一,无序的数据。
(2)List:存储有序的,不唯一的数据。
(3)Set:存储无序的,唯一的数据。
(4)Map:以键值对的形式存储数据,以键取值,键不能重复,值能重复。

3.【List 接口】

(1)常用方法:
 ①add()在列表的最后添加元素
 ②add(index.obj)在列表的指定位置插入元素
 ③size();返回当前列表的元素个数
 ④get(int index);返回下标为index的元素
 如果没有泛型约束,返回Object类型,需要强转,如果有泛型约束,返回约束类型,无需强转。
 ⑤clear();清除列表中的所有数据
 isEmpty();检测列表是否为空
 ⑥contains()方法,传入一个对象,检测列表中是否包含该对象。
 如果传入的是String和基本数据类型,可以直接对比。
 如果传入的是实体类对象,则默认只比对两个对象的地址,因此,需要在实体类重写equals()方法。
 ⑦indexof()传入一个对象,返回在该对象在列表中首次出现的地址。
 lastindexof()返回最后一次的地址。
 ⑧传入一个下标,或者一个对象,删除指定元素
 如果传入下标,返回被删除的元素对象,如果下标大于size(),显示越界异常。
 如果传入对象,则要求重写equals方法,返回true或false显示删除是否成功。
 ⑨set(index,obj)用新传入的对象,将指定位置的元素替换掉,返回被替换掉的元素对象。
 sublist()截取一个子列表返回list类型
 toArray()将列表转成数组,返回一个Object[]类型
 (2)ArrayList(例如新闻列表)
 是实现了长度可变的数组,在内存空间中开辟一串连续的空间,长度可以随时修改,这种存储结构再循环
 遍历和随机访问元素的速度比较快。
 (3)LinkedList
 使用链表结构存储数据,再插入和删除元素师速度比较快。
 LinkedList的特有方法:
.addfirst();开头插入元素
.addlast();结尾插入元素
 removefirst()删除第一个元素
 removelast()删除最后一个元素。返回被删除的元素
 peekfirst();检索但不删除第一个元素
 peeklast();检索但不删除最后一个元素
 pullfirst()检索删除第一个元素
 getfirst()检索但不删除第一个元素
 getlast()检索但不删除最后一个元素

  1. //ArrayList是实现类,实现List接口。
  2. ArrayList list=new ArrayList();
  3. list.add("list1");
  4. list.add("list2");
  5. list.add("list3");
  6. list.add("list4");
  7. list.add(2,"list0");
  8. System.out.println(list.contains("list1"));//返回true
  9. System.out.println(list); //返回数组类型的
  10. /**
  11. * 使用for循环遍历列表
  12. */
  13. for(int i=0;i<list.size();i++){
  14. if(list.get(i) instanceof String){
  15. String s=(String)list.get(i);//向下转型,强转 Integer强转会出现转换异常。
  16. System.out.println(s);
  17. }else{
  18. Integer s=(Integer) list.get(i);
  19. System.out.println(s);
  20. }
  21. }//返回字符串的形式

1.【set接口】
(1)常用方法:与list接口基本相同。
 但是由于Set接口中的元素是无序的,因此没有用下标方法。
 例如get(index),remove(index)add(index,obj)
(2)Set的特点:无序,唯一
(3)HashSet,底层是调用HashMap的相关方法,传入数据后,根据数据的hashcode进行散列运算,得到一个散列值后在进行运算,
 确定元素在序列中存储的位置。
 HashSet如何确定两个对象是否相等:
 ①先判断对象的HashCode(),如果HashCode不同,肯定不是一个对象。
 如果HashCode相同,继续判断equals方法
 ②重写equals()方法。
 所以使用HashSet存储实体对象时,必须重写对象的HashCode()和equals()两个方法;
(4)LinkedHashSet,在HashSet的基础上,新增了一个链表,
  用链表来记录HashSet元素存放的顺序,因此使用迭代器遍历时,可以按照放入的顺序一次独处。
(5)TreeSet将存入的元素进行排序,然后再进行输出,如果存入的是实体对象,那么实体类必须实现comparable接口,并重写compareTo方法。
 或者也可以在实例化TreeSet的同时,通过构造函数传入一个比较器(一个实现了comparator接口并重写了compare的方法的对象)
 //使用匿名内部类拿到一个比较器对象

  1. Set<Person> set=new TreeSet<Person>(new Comparator(){
  2. public int compare(Person p1,Person p2){
  3. return p1.getId()-p2.getId();
  4. }
  5. });

 //自定义一个比较类,实现Comparator接口。

  1. Set<Person> set=new TreeSet<Person>(new Compare());
  2. class Compare implements Comparator(){
  3. //重写compare方法
  4. }

(5)[comparable 接口和comparator的区别]
①Comparable由实体类实现,重写ComparaTo()方法
 实体类实现Comparable接口以后,TreeSet使用空参构造即可。
②Comparator需要单独一个单独比较类进行实践,重写compare方法。
 实例化TreeSet的时候,需要传入一个比较类的对象。
2.【Map】

(1)Map接口特点:以键值对的形式存储数据,以键取值键不能重复,值不能重复。

(2)Map接口的常用方法:       

  .clear() 

  replace(key,value)①put(key,value);向map的最后追加一个键值对

  map1.put(“001”, “小红”);
②get(key);通过建,收到值
  System.out.println(map1.get(“001”));
③.clear();清除Map中的所有数据
④containsValue(obj)检测是否包含指定的值
   containsKey(obj)检测是否包含指定的键,如果传入对象,需要重写equals方法。
(3)【HashTable和HashMap的区别】
 ①HashTable是线程安全的(线程同步),HashMap是线程不安全的(线程不同步)
 ②HashTable的键不能为null,HashMap的键可以为null
 ③HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75。
 ④HashMap扩容时是当前容量翻倍即:capacity*2,Hashtable扩容时是容量翻倍+1即:capacity*2+1。
 ⑤HashMap继承了AbstractMap,HashTable继承Dictionary抽象类,两者均实现Map接口。
 ⑥在HashMap 中不能用get()方法来判断HashMap 中是否存在某个键,而应该用containsKey(),方法来判断。Hashtable 的键值都不能 为null,所以可以用get()方法来判断是否含有某个键。
(4)【LinkedHashMap】(无序)
 可以使用链表,记录数据放入的次序,进入让读出的顺序和放入的顺序一致,与LinkedHashSet一致
   Map<String,String> map1=new LinkedHashMap<String,String>();
(5)【TreeMap】
 根据键的顺序,进行排序后,输出。如果传入的是实体对象,必须重写比较函数,详见TreeSet
   Map<String,String> map1=new TreeMap<String,String>();

  1. Map<String,String> map1=new Hashtable<String,String>();
  2. map1.put("001", "小红");
  3. map1.put("002", "小王");
  4. map1.put("003", "小绿");
  5. map1.put("004", "小黄");
  6. map1.put(null, "小和");
  7. map1.replace("001", "小哈");//更改
  8. System.out.println(map1);
  9. System.out.println("****************");
  10. System.out.println(map1.get("001"));
  11. System.out.println("****************");
  12. System.out.println(map1.containsKey("001"));
  13. System.out.println(map1.containsValue("小绿"));//

  1. Map<String,String> map1=new HashMap<String,String>();
  2. map1.put("001", "小红");
  3. map1.put("002", "小王");
  4. map1.put("003", "小绿");
  5. map1.put("004", "小黄");
  6. map1.put(null, "小和");
  7. map1.replace("001", "小哈");//更改
  8. System.out.println(map1);
  9. System.out.println("****************");
  10. System.out.println(map1.get("001"));
  11. System.out.println("****************");
  12. System.out.println(map1.containsKey("001"));
  13. System.out.println(map1.containsValue("小绿"));//

(6)遍历Map的方式

①遍历Map的方式1:KeySet

  1. System.out.println("****************");
  2. Set<String> keys=map1.keySet();
  3. Iterator<String> it=keys.iterator();
  4. while(it.hasNext()){
  5. String key=it.next();
  6. System.out.println(key+"*******"+map1.get(key));
  7. }

② 遍历Map的方式2:values

  1. System.out.println("****************");
  2. Collection<String> values=map1.values();
  3. Iterator<String>it1=values.iterator();
  4. while(it1.hasNext()){
  5. System.out.println(it1.next());//可以以键取值,不能以值取键
  6. }

③遍历Map的方式3:entrySet

  1. System.out.println("****************");
  2. Set<Map.Entry<String,String>> set2=map1.entrySet();
  3. /*foreach*/
  4. for(Map.Entry<String, String> entry:set2){
  5. System.out.println(entry.getKey()+"****"+entry.getValue());
  6. }
  1. /*Entry*/
  2. System.out.println("****************");
  3. Iterator<Map.Entry<String, String>> it3=set2.iterator();
  4. while(it3.hasNext()){
  5. Map.Entry<String, String>entry =it3.next();
  6. //entry 是Java给我们提供的一种特殊的数据类型其实是一个数据对。
  7. //键就是这条记录的键,使用getkey()去到
  8. //值就是这条记录的值,使用getValue()取到
  9. System.out.println(entry.getKey()+"****"+entry.getValue());
  10. }

 Collections是Java中专门用于操作集合的工具类。

Collection是一个接口。

1.向集合中添加多个数据

(1)传入数据

  1. ArrayList<String> list = new ArrayList<String>();
  2. list.add("test04");
  3. list.add("test09");
  4. list.add("test03");
  5. list.add("test02");
  6. list.add("test01");
  7. list.add("test07");
    Collections.addAll(list, "01","02","test01");
    System.out.println(list);

(2)传入对象

  1. List<PersonDemo> list1 = new ArrayList<PersonDemo>();
  2. list1.add(new PersonDemo(1,"zhangsan"));
  3. list1.add(new PersonDemo(5,"lisi"));
  4. list1.add(new PersonDemo(2,"wanger"));
  5. list1.add(new PersonDemo(6,"zhaowu"));
  6. list1.add(new PersonDemo(3,"liergou"));
  7. Collections.addAll(list1, new PersonDemo(10,"zhngsan"),new PersonDemo(8,"wangr"));
  8. System.out.println(list1);

 

2.将集合中的所有元素,全部替换为指定元素。把list里的内容替换成呵呵哒。

  1. Collections.fill(list, "呵呵哒!");
  2. System.out.println(list);

3.排序。

(1)sort方法: 对集合中的数据进行排序。

  1. Collections.sort(list1);
  2. System.out.println(list1);

(2)如果集合存储的是一个实体对象,那么:

 ① 实体类实现comparable接口,并重写CompareTo方法;
 ② 在sort的第二个参数,传入比较器。 比较器需实现comparator接口,并重写compare方法。

  1. Collections.sort(list1, new Comparator<PersonDemo>() {
  2. @Override
  3. public int compare(PersonDemo o1, PersonDemo o2) {
  4. // TODO Auto-generated method stub
  5. return o1.getId() - o2.getId();
  6. }
  7. });
  8. System.out.println(list1);

4.使用binarySearch,那么集合必须先排序。
同样,如果比较的是实体对象,依然需要通过两种方式实现比较器。

  1. Collections.sort(list1);
  1. System.out.println(Collections.binarySearch(list1, new PersonDemo(6,"zhaowu")));

 ②匿名内部类比较器

  1. System.out.println(Collections.binarySearch(list1, new PersonDemo(6,"zhaowu"),
  2. //匿名内部类
  3. new Comparator<PersonDemo>() {
  4. @Override
  5. public int compare(PersonDemo o1, PersonDemo o2) {
  6. // TODO Auto-generated method stub
  7. return o1.getId() - o2.getId();
  8. }
  9. }
  10. ));

(4)拿到集合中最大、最小的值。

  1. System.out.println(Collections.max(list1));
  2. System.out.println(Collections.min(list1));

5..replaceAll(): 将列表的指定值,用新值替换。

如果是实体对象,需要在实体类中重写 equals()方法。

  1. System.out.println(Collections.replaceAll(list1, new PersonDemo(1,"zhangsan"),
  2. new PersonDemo(1,"zhangsansan")));//后面返回前面,返回boolean类型
  3. System.out.println(list1);//返回替换后的列表

6.反转列表中的所有元素。(前后交换)

  1. Collections.reverse(list1);
  2. System.out.println(list1);

7.对集合的元素,进行随机排序。

  1. Collections.shuffle(list1);
  2. System.out.println(list1);

8.将集合中指定的元素位置,进行交换。(把第三个和第0个交换)

  1. Collections.swap(list1, 0, 3);
  2. System.out.println(list1);

 

1、 [泛型]
(1) 泛型就是“参数化类型”。 
在定义类型时,不将类型定死,而是采用泛型参数的形式进行定义。调用时传入具体的泛型参数。
2、[泛型类的特点]
 在声明类的时候,进行泛型约束,这样的类,称为泛型类。

  1. class Test<T>{ // <T> 可以理解为泛型声明是的形参。可以用任何字母代替。 常用T N E
  2. // 在泛型类中,T就可以当做特殊的数据类型进行使用
  3. private T arg;
  4. }
  5. // 泛型调用时,需要将实际的数据类型进行传入。
  6. Test<String> test1 = new Test<String>("姜浩真帅!");
  7. Test<Integer> test2 = new Test<Integer>(123);

(1) 泛型只在编译阶段生效。 同一个类通过不同泛型拿到的对象,使用getClass()判断是属于同一个类的。

  1. System.out.println(test1.getClass() == test2.getClass());
  2. // 取到的test1的类为 Test类,而不是Test<String>

(2)同一个类,通过不同泛型拿到的对象,相互不兼容。 不能互相赋值。

  1. test2 = test1; // test1与test2不兼容。

 即便,声明的泛型数据类型有父子类关系,那么用这两个数据类型声明的泛型类,还是不兼容。

  1. Test<Integer> test2 = new Test<Integer>(123);
  2. Test<Number> test3 = new Test<Number>(123);
  3. test3 = test2; // 依然不兼容。

(3) 泛型类,在实例化的时候,可以不传入泛型。 类中的数据类型,以赋值时传入的变量类型为主。

  1. Test test3 = new Test(); // 实例化泛型类,没有传入泛型实参
  2. test3.setArg("123"); // 类中的泛型变为String
  3. test3.setArg(456); // 类中的泛型被修改为Integer

(4) 实例化泛型时,只能传入类名,可以是系统类也可以是自定义的实体类,但不能传入基本数据类型。

  1. Test<int> test1 = new Test<int>(); // ×

(5)泛型约束时,可以同时约束多个泛型: 

  1. class Test1<T1,T2>{
  2. public T1 arg1;
  3. public T2 arg2;
  4. }
  5. Test1<String,Integer> test4 = new Test1<String,Integer>();

(6)不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的,编译时会出错。

  1. test2 instanceof Test2<Integer>; // ×
  2. test2 instanceof Test2; //

3.[泛型通配符与上下边界]
(1) 为了解决,同一个类的多个不同泛型对象,相互不兼容的问题。 可以使用泛型通配符:?

  1. Test<?> test2 = new Test<String>();
  2. // ? 表示可以兼容所有类的数据类型。

(2) 泛型通配符上边界: 使用? extends 类名,表示通配符只支持指定类及指定类的子类。

  1. Test<? extends Number> test5 = new Test<Number>(); //
  2. Test<? extends Number> test5 = new Test<Integer>(); //
  3. Test<? extends Number> test5 = new Test<String>(); // ×

(3) 泛型通配符下边界: 使用 ? super 类名,表示通配符只支持指定类及其超类。

  1. Test<? super Integer> test6 = new Test<Integer>(); //
  2. Test<? super Integer> test6 = new Test<Number>(); //
  3. Test<? super Integer> test6 = new Test<String>(); // ×

4. [泛型接口]
(1) 声明泛型接口:

  1. interface inter<T>{
  2. void Test(T t);
  3. }

(2)实现类,如果实现泛型接口,那么不能直接使用接口的泛型,需要重新声明:

  1. class Test3<T> implements inter<T>{
  2. @Override
  3. public void Test(T t) {}
  4. }

(3)如果实现类,不想作为泛型类。 那么,可以在实现接口时,直接给接口的泛型赋值:

  1. class Test3 implements inter<String>{
  2. @Override
  3. public void Test(String t) {}
  4. }

5. [泛型方法]
(1) 泛型方法可以独立于泛型类,在任何类中都可以单独使用:

  1. class Test{
  2. public static <T> void test(T t){
  3. }
  4. }
  5. //调用:
  6. Test.test("String");
  7. Test.test(int);

(2) 使用泛型方法,可以实现可变参数的方法:

  1. class Test{
  2. // 使用T... 表示可以接受N个 任意类型的参数; 也可以接受数组
  3. public static <T> void test(T... t){
  4. }
  5. }

 调用: Test.test(“String”,”String2″,123,true);
Test.test(new int[]{123,456,789});
(3)只有在方法中声明了<T>的方法,才叫泛型方法。
而如果在方法中,使用了类的泛型,这不能称为泛型方法。

  1. class Test<T>{
  2. // 这个不是泛型方法
  3. public void test(T t){}
  4. }

 注意: 静态方法不能使用类泛型。 只能将静态方法,单独声明为泛型方法。

 Math类位于java.lang包,不需要导包。

1.返回圆周率。

  1. System.out.println(Math.PI);

2.返回绝对值。

  1. System.out.println(Math.abs(-10));//绝对值,返回10

3.立方根。

  1. System.out.println(Math.cbrt(27));//返回3

4.平方根。

  1. System.out.println(Math.sqrt(9));//返回3

5.最大最小值。

  1. System.out.println(Math.max(20, 19));
  2. System.out.println(Math.min(20, 19));

6.求a的b次方幂。

  1. System.out.println(Math.pow(a, b));

7.floor返回一个小于指定浮点数的第一个整数,返回的是double类型,10.0。

  1. System.out.println(Math.floor(10.5));//10.0
  2. System.out.println(Math.floor(-10.5));//-11.0

8.ceil返回一个大于指定浮点数的第一个整数,返回的是double类型,11.0。

  1. System.out.println(Math.ceil(10.5));//11.0
  2. System.out.println(Math.ceil(-10.5));//-10.0

9.进行四舍五入,返回一个整数类型,若果传入double返回long,如果float返回int。

  1. System.out.println(Math.round(10.5f));//11
  2. System.out.println(Math.round(10.3d));//10

10.保留三位小数。

  1. public static double rounds(double num,int count){
  2. return Math.round(num*Math.pow(10, count))/Math.pow(10, count);
  3. }
  4. System.out.println(rounds(10.354546,3));//diao用
  1. System.out.println(Math.round(10.354546*Math.pow(10, 3))/Math.pow(10, 3));//10.355

11.返回最接近参数的一个整数,如果是10.5与10和11同时接近,那么返回偶数10。

  1. System.out.println(Math.rint(10.5));//10

12.返回【0,6)的int(左闭右开)随机一个。

  1. System.out.println((int)(Math.random()*6));// 强转成int返回【1,6)的

13.返回ASCII码值。

  1. System.out.println(Arrays.toString("abcdef".getBytes()));//返回数组97 98 99 100 101 102 103

14.判断是否有.java返回boolean。

  1. System.out.println("abc.java".endsWith(".java"));

15.把0替换成o,把I替换成i。

  1. String s="43434344250000000ooooooooooIIIIIIIIIi";
  2. System.out.println(s.replace("0", "o"));//4343434425oooooooooooooooooIIIIIIIIIi
  3. System.out.println(s.replace("I", "1"));//43434344250000000oooooooooo111111111i

1.date空参构造: 取到当前时间。

  1. Date date = new Date();
  2. System.out.println(date);

2.setTime(): 传入一个长整型,重新设置date时间。

  1. Date date = new Date();

    date.setTime(1000*60*60*24);//计算机元年
  1. System.out.println(date);

3.传入一个long类型的时间戳,取到指定时间。

date.getTime(): 取到一个时间的时间戳: 从0时区,1970年1月1日0:0:0 到当前时间的毫秒数。

  1. Date date = new Date();
  2. date.setTime(1000*60*60*24);
  3. System.out.println(date.getTime());

4.compareTo(): 前面>参数 返回 1 前面<参数 返回 -1 前面=参数 返回 0

 equals(): 比对两个时间是否相等。
   before(): 检测一个时间是不是在指定时间之前
   after(): 检测一个时间是不是在指定时间之后

  1. System.out.println("3******************");
  2. System.out.println(date.before(date2));
  3. System.out.println(date.after(date2));
  4. System.out.println(date.compareTo(date2));
  5. System.out.println(date.equals(date2));

5.求出从95年到现在的年数。

  1. Date date = new Date();
  2. System.out.println(date);//当前时间
  3. Date date3 = new Date(95, 11, 23);
  4. System.out.println((date.getTime() - date3.getTime())/1000/60/60/24/365);//求出从95年到现在的年数

6.日期。

.

7.format(): 用于传入一个Date类型的参数,并返回格式化之后的字符串。

parse(): 将字符串格式的时间,转成Date类型。 要求传入的字符串格式,必须与实例化时的模式,保持完全一致
toPattern(): 返回当前格式化的模式字符串。

  1. SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E");
  2. String dateFormat = sf.format(new Date());
  1. Date date3 = null;
  2. try {//捕获异常
  3. date3 = sf.parse("2018年04月13日 14:09:47 星期五");
  4. } catch (ParseException e) {
  5. // TODO Auto-generated catch block
  6. e.printStackTrace();
  7. }
  8. System.out.println(dateFormat);
  9. System.out.println(date3);
  10. System.out.println(sf.toPattern());

1. Calendar日历类是一个抽象类,不能直接通过new拿到对象,必须使用 Calendar.getInstance();拿到。

  1. Calendar calendar = Calendar.getInstance();
  2. System.out.println(calendar);

2.在原来的基础上减了两天。

  1. calendar.add(Calendar.DAY_OF_MONTH, -2);
  2. System.out.println(calendar);

3.getTime 返回一个日期对象。

  1. Date date4 = calendar.getTime();
  2. System.out.println(sf.format(date4));

4.根据calendar提供的常量,获得指定字段。

  1. System.out.println(calendar.get(calendar.MONTH));
  2. System.out.println(calendar.get(calendar.DAY_OF_WEEK));

5.计算当前为星期几。

  1. String[] arr = {"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};
  2. int week = calendar.get(calendar.DAY_OF_WEEK)-1;
  3. System.out.println(arr[week]);

Random()类:取随机数
两种构造:
①空参构造
②传入一个种子数
③传入一个种子数,只要种子数相同,那么在相同次数(Random)取到的随机数肯定相同,这是伪随机数。

1.随机输出一个整数。

  1. Random ran=new Random();//随机输出正负均可
  2. System.out.println(ran.nextInt());

2.nextInt()随机获得一个整数

 nextInt(n)随机获得从0到n的随机数
    nextDouble();

  1. Random ran1=new Random(10);
  2. System.out.println(ran1.nextInt(10));//10以内随机
  3. System.out.println(ran1.nextInt(10));//10以内随机
  4. System.out.println(ran1.nextInt(10));//10以内随机
  5. System.out.println(ran1.nextInt(10));//10以内随机

3.返回毫秒数。

  1. Date date=new Date();
  2. System.out.println(date.getTime()/1000/60/60/24);
  3. System.out.println(System.currentTimeMillis());

4.随机返回[95,103)。

  1. Random ran=new Random();
  2. System.out.println(ran.nextInt(8)+95);

枚举类是一种特殊的类,里面的值全部都是静态常量。
每个枚举值都相当于一个本类对象,只不过(对象的值就是对象的名)调用对象的toString方法打印的是对象名。

  1. enum Color{
  2. /**
  3. * 每一个枚举值都是一个本类对象。
  4. * 、所以声明一个枚举值,相当于执行下列代码
  5. * public static final BLUE=new Color();
  6. * public static final PINK=new Color();
  7. * public static final YELLOW=new Color();
  8. */
  9. /**
  10. * 在枚举类中,枚举值必须要放在第一行,其他所有代码只能放在枚举值的后面。
  11. *
  12. * 枚举类中的构造函数,只能是私有化的,在声明枚举值时,自动调用。
  13. */
  14. BULE,RED,YELLOW,GREEN,PINK;//本类对象
  15. private Color(){//构造函数在常见对象使用
  16. System.out.println("hahahahahah");//输出5次,枚举值的个数。
  17. }
  18. }
  1. System.out.println(Color.BULE);

1.toString方法自动调用。

  1. System.out.println(Color.BULE.toString());

调用对象的toString方法打印的是对象名。

返回BULE。

2.取到枚举类中所有枚举值。

  1. Color [] colors=Color.values();
  2. for(Color color:colors){
  3. System.out.println(color.toString());
  4. }

3.声明一个Person枚举类型的类。

  1. enum Person{
  2. Person1 ("张",12),Person2 ("li",22),Person3 ("chen",22),Person4 ("liu",13),Person0;
  3. private String name;
  4. private int age;
  5. private Person(String name,int age){
  6. this.name=name;
  7. this.age=age;
  8. }
  9. private Person(){
  10. this.name="默认";
  11. this.age=0;
  12. }
  13. public String toString(){
  14. return name+"------"+age;
  15. }
  16. }
  1. System.out.println(Person.Person0);
  2. System.out.println(Person.Person1);//写toString方法

单例模式:确保某一个类只能产生一个实例。

1.设计思路:

①将构造函数私有化,确保类外部不能使用new关键字自己创建对象。
②在类内部实例化一个对象,并通过静态方法返回。

  1. private static Singleton sing =new Singleton();
  2. //如果这局部是静态的,public static Singleton getInstance()方法不能调用
  3. private Singleton(){//1
  4. System.out.println("单例模式");
  5. }

2. 恶汉式单例模式,在类加载的时候,就创建了一个对象。

缺点:在类加载的时候就实例化对象,提前占用系统资源
优点:线程安全。

  1. private static Singleton sing =new Singleton();
  2. public static Singleton getInstance(){
  3. return sing;
  4. }

3.懒汉式单例模式。

优点:解决了恶汉式单例,一加载就提前占用资源的问题。
 缺点:线程不安全。

  1. private static Singleton sing =null;
  2. public static Singleton getInstance(){
  3. if(sing==null){
  4. sing =new Singleton();
  5. }
  6. return sing;
  7. }

4.synchronized同步锁。

使用synchronized同步锁,对方法进行加锁,确保懒汉式单利可以线程安全。
将一个方法或者是代码块进行加锁,同一时间只允许一个线程访问。
 缺点:每次都需要锁住方法,每一个方法或代码块 ,效率低下。

  1. private static Singleton sing =null;
  2. public static synchronized Singleton getInstance(){//线程锁synchronized
  3. if(sing==null){
  4. sing =new Singleton();
  5. }
  6. return sing;
  7. }

5.双重加锁的懒汉模式。

只有第一个Sing为null时,才进行线程锁,
当后续sing不为null时,就无需线程锁,可以允许多个线程同时拿走sing。

  1. private static Singleton sing =null;
  2. public static synchronized Singleton getInstance(){//锁住哪个类的对象
  3. if(sing==null){
  4. synchronized (Singleton.class) {
  5. if(sing==null){
  6. sing =new Singleton();
  7. }
  8. }
  9. }
  10. return sing;
  11. }

6.静态内部类实现单例:

优点:解决了恶汉式提前占用资源的问题,解决了懒汉式线程不安全的问题。

  1. private static class Singleton1{//不能是public外面可以直接实例化,每次都调用,不能实现单例
  2. private static Singleton sing =new Singleton();
  3. }
  4. public static Singleton getInstance(){
  5. return Singleton1.sing;
  6. }

 

 

版权声明:本文为gcywj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/gcywj/p/8836777.html