JAVA面向对象2

一泛型介绍

1 .1 语法格式

<无意义的字符> 一般放

//无返回值  有参数的泛型方法
 public static <T> void  test(T t){
     sout("t");
 }
// 有返回值 有参数的泛型方法
 public static <T> T test2(T t){
     return t;
 }

1.2 自定义泛型在类中使用

class 类名 <T>{
}

1.3 自定义泛型在接口中使用

interface  接口名字<T> {


		}

案例一

interface demo <T>{
 public T test(T t);//有参数有返回值的泛型类型
 public void (T t);//有参数无返值类型。
 // 在来一个类 去实现这个接口泛型的实现类
 // 接口带有泛型,那么它的实现类必须带有泛型,而且你的泛型必须和接口的泛型一致
 class demo1<T> implements demo<T>{
  public void (T t){
  System.out.println("hello world";
   public T test(T t){
   return a+b;
   }
 }

1.4 泛型在抽象类中使用

abstract demo <T> {

}
//案例一
abstract class B<T> {
	public abstract void getArgs(T t);
	public void get(T t) {
		System.out.println(t);
	}
	public abstract T getArgs1(T t);
}
class TestB<T> extends B<T> {

	@Override
	public void getArgs(T t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}
	@Override
	public void get(T t) {
		// TODO Auto-generated method stub
		System.out.println(t);
	}

	@Override
	public T getArgs1(T t) {
		// TODO Auto-generated method stub
		return t;
	}
	
}
public class Demo6 {
	public static void main(String[] args) {
		TestB<String> testB = new TestB<String>();
		testB.getArgs("bh");
	}

}

二 集合

2.1 Collection 和Collections的区别?

Collection : 是list 和set集合的父类。
Collections: 是集合的工具类

Collection<E>中的方法,遵从Collection接口的实现类或者子接口都可以使用这些方法。
    增:
    	boolean add(E e);添加指定的元素到指定的集合中,采用的尾插法
    	boolean addAll(Collection<? extends E>);添加另外一个集合到当前集合对象中。要求添加的对象集合的泛型和当前对象集合保持一致
    删:
   		boolean  remove(Object obj);删除集合中的某一个元素。
    	boolean removeAll(Cololection<? extends E> e);删除两个集合中的交集
    	void clear();清空所有的元素
    查:
    	int size();获取集合中元素的个数
    	Object[] toArray();将集合转为Object类型的数组
    	boolean contains(Object o);判断数据是否在集合中
    	boolean containsAll(Cololection<? extends E> e);判断一个集合是否是另外一个集合的子集合
    	boolean isEmpty();判断元素是否为空

2.2 list 集合

list 集合特点 : 有序元素可以重复

2.2.1 ArraysList 和LinkedList

ArraysList: 是基于数组的实现。默认容器量为10 ,一旦这个集合的容器量不足,就会自动扩容,使用是低层代码grow。是扩容原来的1.5倍。
ArraysList 有一些特征: 查找快,增删慢。
LinkedList : 是基于数组+链表的实现。第一个元素没有前置节点,最后的元素没有后继。连接元素 是通过前面元素的后继 跟第二个元素的前置进行连接
所以 查找慢 增删快。

2.3 Set 集合

set 接口里面实现的子类有 hashset treeset
set 集合特征 : 无序 元素不能重复。

/**
 * hashSet是基于hashMap(哈希表)实现
 * 不允许有重复元素 可以又一个null元素
 * 添加元素是把元素值作为hashMap的key
 * 排除元素重复是通过equals来检查对象是否相同
 * 判断两个对象是否相同,先判断两个对象hashcode是否相同 如果两个hashcode相同,不一定是相同对象
 * 如果两个对象的equals相同 则一定hashcode相同;
 * 2 hashcode 是基于数组加链表,数组中每个元素以链表的方式存储数据;
 *
 */
/**
     * 由此可见:treeSet是有序的 元素不能重复
     */

2.4 Map 集合

1 将映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射一个值
2 以键值对方式存储一对对象 Key不能重复 Value可以重复
3 具体实现类有 : hashMap TreeMap Hashtable

2.4.1 map集合遍历方式
package com.mmc.g_map;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * map接口:
 * 以key—value存储数据 key不能重复 value可以重复
 * 实现的接口有 hashMap treeMap Hashtable;
 */
public class MapDemo {
    private static void getHashMap(){
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"hello");
        map.put(2,"world");
        map.put(3,"good");
        map.put(4,"morning");
        map.put(5,"afternoon");
        /*
         1 通过entrySet进行集合遍历
         */
        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
        entrySet.forEach((s)-> System.out.println(s.getValue()));
        /*
        2 通过keyset遍历
         */
        Set<Integer> keys =map.keySet();
        for (Integer i : keys) {
            String value = map.get(i);
            System.out.println(i+"-->"+value);
        }
        /*
        3 直接遍历values
         */
        Collection<String> vaules=map.values();
        for (String va:vaules) {
            System.out.println(va);
        }
        /*
         4 foreach 是实现 BiConsumer这个接口 传两个参数 
         */
        map.forEach((key,vaule)-> System.out.println(key+"-->"+vaule));
    }
    public static void main(String[] args) {
        getHashMap();
    }
}

2.4.2 HashMap实现原理
/**
 * map接口:
 * 以key—value存储数据 key不能重复 value可以重复
 * 实现的接口有 hashMap treeMap Hashtable;
 * 二 HashMap实现原理
 * hashMap是基于数组加链表 在jdh1.8之后是以数组加链表加红黑树实现的
 * static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;默认加载因子为0、75 默认数组大小为16 1左移4 相当于2的4次方
 * 三 把对象如何存入哈希表中;
 * 把key对象通过hash()的方法计算hash值,然后这个长度对数组取余(默认长度16);然后来确定key在数组中位子,如果有相同的key
 * 的对象时,以链表结构存储;在jdk8后 当存储达到链表长度大于8。就会转换为红黑树结构存储;
 * 四 当数组容量达到0。75,如何扩充
 *  将当前数组容量向左移一位,然后在根据hash()计算哈希值在数组中位置
 * 五 线程不安全,适合在单线程使用
 */

三 匿名内部类

3.1 基于抽象类的匿名内部类

*** 之前的抽象类不能倍实例化,但是现在可以使用匿名内部类去实现实例化

package com.qfedu.c_anno;

//定义一个抽象类
abstract class Animal{
	public abstract void eat();
}
//之前再新建一个类去继承Animal,然后重写eat方法
//
public class Demo1 {
	public static void main(String[] args) {
		//现在直接可以这样来写
//		Animal animal = new Animal() {//实例化抽象类的时候顺便把未实现的方法实现掉
//			@Override
//			public void eat() {
//				// TODO Auto-generated method stub
//				System.out.println("吃饭");
//			}
//		};
//		animal.eat();
		new Animal() {
			
			@Override
			public void eat() {
				// TODO Auto-generated method stub
				System.out.println("在吃饭");
			}
		}.eat();//匿名对象.方法();
	}
//官方文档中关于匿名内部类说过英文的  减少代码的量
}
package com.mmc.abstranct2;

/**
 * 这一种方法在开发中常用
 */
public class StudentTest2 {
    public static void main(String[] args) {
        test(new Student() {
            @Override
            public void study() {
                System.out.println("她在学后端知识");
            }
        });
    }
    public static void test(Student student){
        student.study();
    }
}

3.2 基于接口的匿名内部类

interface Pig {
	public void eat();
}
//不用再单独写一个类去实现这个接口
public class Demo3 {
	public static void main(String[] args) {
		new Pig() {
			@Override
			public void eat() {
				// TODO Auto-generated method stub
				System.out.println("猪吃主食");
			}
		}.eat();
	}

}

四 io流

4.1 io流的分类

4.1.1 按照流的功能方向分

1 输入流 和输出流
输入流:只能从中读取数据,不能写入数据
输出流: 只能从中写入数据,不能读取数据‘

4.1.2 按照流的角色分为

1 字节流和字符流
字节流:InputStream OutputStream 但是这个字节流没有缓存作用
如果想有缓存功能使用 BuffterInputStream 和 BuffterOutputStream。
字符流: Filewriter FileRead 没有缓存作用
Buffter 就具备缓冲作用。

4.2 File类几个判断方法

//是文件
		System.out.println(new File("c:/aaa/1.txt").isFile());
		System.out.println(new File("c:/aaa").isFile());//false
		System.out.println(new File("c:/aaa").isDirectory());//true
		System.out.println(new File("c:/aaa/1.txt").isDirectory());//false
		
		System.out.println(new File("c:/aaa/1.txt").isHidden());//false
		System.out.println(new File("c:/aaa/1.txt").isAbsolute());//true
		System.out.println(new File("c:/aaa/8888.txt").exists());//false

4.3 使用流的方法copy文件

class test2{
public static void main(String[] args) throws IOException {
test4();
}
public static void test4() throws IOException{
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream(new File("C:\\Users\\梅梦成07\\Desktop\\知识\\33.txt")));
        BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream(new File("D:\\working1\\day20-File\\3.txt")));
        long strat=System.currentTimeMillis();
        byte[] bytes=new byte[1024];
        int length=-1;
        while ((length=bis.read(bytes))!=-1){
            bos.write(bytes,0,length);
        }
        bos.close();
        bis.close();
        long end = System.currentTimeMillis();
        System.out.println(end-strat);
    }
    }

五 多线程

5.1 进程和线程

进程: 进程是需要通过系统的分配,获取系统当前的CPU,内存,显卡,网络等这些资源
​ 1.独立性
​ 2.互斥性
线程: 线程是组成进程的最小基本单位,一个进程至少包含一个线程。

5.2 创建线程的方式

5.2.1 使用Thread
class MyThread1 extends Thread {
	@Override
	public void run() {
		//for循环
		for (int i = 0; i < 100; i++) {
			System.out.println("我是Mythread1线程里面的代码");
		}
		
	}
}
class MyThread2 extends Thread {
	@Override
	public void run() {
		//for循环
		for (int i = 0; i < 100; i++) {
			System.out.println("我是Mythread2线程里面的代码");
		}
		
	}
}
public class Demo1 {
	public static void main(String[] args) {
		//main一个线程
		//实例化出来一个线程对象
		MyThread1 myThread1 = new MyThread1();
		//通过调用start方法开启线程一定是start方法
		myThread1.start();
		MyThread2 myThread2 = new MyThread2();
		myThread2.start();
		//4个线程    2个myThread   1main   1jvm 垃圾回收器
		for (int i = 0; i < 100; i++) {
			System.out.println("我是main主函数线程");
		}
		
	}

}

5.2.2 实现Runable接口
package com.qfedu.a_thread;

class MyThread4 implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 100; i++) {
			System.out.println("MyThread" + i);
		}
	}
	
}
public class Demo2 {
	public static void main(String[] args) {
		//第二种写法
		Thread thread = new Thread(new MyThread4());
		thread.start();//开启线程
		for (int i = 0; i < 100; i++) {
			System.out.println("main:" + i);
		}
	}

}

5.3 了解线程下面的方法

构造方法:

    • Thread() 分配一个新的 Thread对象。
      Thread(Runnable target) 分配一个新的 Thread对象。
      Thread(Runnable target, String name) 分配一个新的 Thread对象。 并对当前线程起个名字哦

成员方法:

​ static Thread currentThread();获取当前线程对象

​ String getName();获取当前线程名字的

​ void setName(String name);设置当前线程的名字

​ void setPriority(int newPriority);设置当前线程的优先级。这个优先级只会增加线程执行的概率

​ 但是真正的会不会优先不一定。int类型的参数,所有线程默认的优先级是5 传值 1-10 1的优先级是最低的,10优先级是最高的

​ int getPriority();获取当前线程优先级的

​ 现在大家想一个问题,线程不可控,乱抢。怎么解决这样的问题呢?现在的解决方案让其睡会,就不抢占了

​ static void sleep();让线程休眠多少毫秒

​ 可以让线程睡一会儿来控制线程的执行的先后顺序的

在run方法中调用Thread.sleep();只能try-catch不能抛

5.4 锁

synchronised   Java 的关键字   同步锁
咱们线程是不安全的,随机抢占的。能不能让其线程有规律的执行呢?
可以的就是加锁。一个线程抢到资源以后,加上锁以后,这个线程先执行结束,会自动的释放锁
其他线程会进行抢占
用法:
	1.修饰一个代码块
	2.修饰一个方法
	3.修饰一个静态方法
	4.修饰一个类
5.4.1 语法格式
synchronised (this) {
		代码块
}

给线程上锁 可以保证当前的线程安全。

5.5 线程中 sleep(),join(),close(),strat();

sleep():因为线程之间具有抢占式,使用sleep关键字,可以保证当前的线程进行休眠、
join(): 开启线程是现执行主线程,然后在执行子线程,然后子线程结束,在执行主线程,至到结束。
close() : 线程比较耗jvm资源,所以要关闭掉
strat() 只有调用这个方法,线程才能执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值