java-3

集合

  • java的集合就像容器一样,是用来存储java类的对象,功能多,方便查找,存入,取出。
  • 集合里面一般只能保存对象,就是保存对象的引用的变量

Collection接口

1.List 有序,可重复

ArrayList:
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高

LinkedList:
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高
Vector:
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低

2.Set 无序,唯一

(1)HashSet:
底层数据结构是哈希表。(无序,唯一)
保证元素唯一性可以依赖两个方法:hashCode()和equals()

HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。

具体实现唯一性的比较过程:

1.存储元素时首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,肯定是不同的对象。
2.hashCode值相同,再比较equals方法。
3.equals相同,对象相同。(则无需储存)

(2)LinkedHashSet:
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一

LinkedHashSet底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。

3.Map接口:

Map用于保存具有映射关系的数据,Map里保存着两组数据:key和value,它们都可以使任何引用类型的数据,但key不能重复。所以通过指定的key就可以取出对应的value。

Map接口有四个比较重要的实现类,分别是HashMap、LinkedHashMap、TreeMap和HashTable。

最主要的区别。

TreeMap是有序的,HashMap和HashTable是无序的。

Hashtable的方法是同步的,HashMap的方法不是同步的。

HashMap

Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许重复,但允许值重复。
HashMap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;
HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
HashMap基于哈希表结构实现的 ,当一个对象被当作键时,必须重写hasCode和equals方法。

LinkedHashMap

LinkedHashMap继承自HashMap,它主要是用链表实现来扩展HashMap类,HashMap中条目是没有顺序的,但是在LinkedHashMap中元素既可以按照它们插入图的顺序排序,也可以按它们最后一次被访问的顺序排序。

TreeMap

TreeMap基于红黑树数据结构的实现,键值可以使用Comparable或Comparator接口来排序。TreeMap继承自AbstractMap,同时实现了接口NavigableMap,而接口NavigableMap则继承自SortedMap。SortedMap是Map的子接口,使用它可以确保图中的条目是排好序的。

在实际使用中,如果更新图时不需要保持图中元素的顺序,就使用HashMap,如果需要保持图中元素的插入顺序或者访问顺序,就使用LinkedHashMap,如果需要使图按照键值排序,就使用TreeMap。

Hashtable

Hashtable和前面介绍的HashMap很类似,它也是一个散列表,存储的内容是键值对映射,不同之处在于,Hashtable是继承自Dictionary的,Hashtable中的函数都是同步的,这意味着它也是线程安全的,另外,Hashtable中key和value都不可以为null。

Object类

传递任何类型的类来使用

显示继承:

public class A extends Object{

}

隐式继承:就是不把extends Object 写出来

方法:

projected Object clone()/** 创建并且返回一个对象的拷贝**/
boolean equals(Object obj) /** 比较两个对象是否相等,用来比较两个引用的虚地址。当且仅当两个引用在物理上是同一个对象时,返回值为true,否则将返回false。**/
      
protected void finalize()   /** 垃圾回收器确定不存在对该对象有更多的有引用的时候,会使用该方法**/
Class<?>getClass()/**获取该对象运行时候的类**/
int hashCode() /**获取对象的hash值**/
void notify() /**唤醒该对象上等待某个线程**/notifyAll则是/**等待的所有线程
String toString /**返回对象的字符串表示形式**/
void wait() /**让当前线程进入等待状态**?/

java序列化

就是把你得到对象拿出来,要把它封装起来。可以方便可以在网络上传输。

要想序列化成功要满足两个条件

该类必须实现 java.io.Serializable 接口。

该类的所有属性必须是可序列化的。

主要的类

//在项目中,服务端和客户端交互时,获取客户端传过来的信息时用这个会更好,否则可能会存在数据乱序的问题

序列化 ObjectOutputStream负责将对象写入字节流。

  ObjectInputStream objectInputStream = new ObjectInputStream(clientSocket.getInputStream());

反序列化 ObjectInputStream从字节流重构对象。就是把对象从数据源还原回来

User userInformation=(User)objectInputStream.readObject();

多线程

多任务:

**理解:**人在吃饭时又玩手机,同时进行

多线程:

**理解:**打游戏时,它可以使多人一起打,多人相互独立不影响的去执行同一件事情。主路和子路,各走各的同时进行相互不影响,效率高

程序.进程(process)

编写的代码,是一个静态的概念,把代码跑起来就是一个进程.

进程(process).线程(thread)

一个进程可以有多个线程

**理解:**就如看电视的时候,既可以听到电视的声音,也可以看到电视中的弹幕

一个进程里面至少要有一个线程,这样才有存在的意义,

进程是系统分配的,线程才是cpu和执行的单位

存在关系:

程序》进程》线程(多个,mian是主线程

核心概念

  • 线程是独立的执行路径
  • 要是程序在运行的时候没有创建线程的话,后台也会有多个线程在
  • 有多个线程的话,运行的由调度器安排,不能人为去控制
  • main()是主线程,是系统的入口,执行与整个程序
  • 同一份资源操作,会有存在资源抢夺问题,需要加入并发控制。(比如买票时,人数大于票数的,就会加入并发进行排队,而不能同时)

线程的创建

java 提供了三种创建线程的方法:

  • 通过实现 Runnable 接口;
  • 通过继承 Thread 类本身;(可以实现Runnable接口)
  • 通过 Callable 和 Future 创建线程。

Thread类

创建一个新的执行线程的方法

1.将类声明为Thread类的子类,然后这个子类应该重写run类的方法Thread,然后分配启动子类的实例

 class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

自定义线程类继承Thread类

重写run方法,编写线程实体

创建线程对象,调用start方法启动线程(每次执行的输出都不一样,因为是由cpu进行调度的)

public class Test extends Thread{

    @Override
    public void run() {
        //run方法线程
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码");
        }
    }

    public static void main(String[] args) {
        //main主线程
        //创建线程对象
        Test test=new Test();
        test.start();
   
        //main主线程
        for (int j = 0; j < 20; j++) {
            System.out.println("我在学习线程");
        }

    }
}

Runnable接口

推荐使用Runnable接口,这样还是使用其他接口

2.声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

lass PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }

定义MyRunnable类是实现Runnable接口

实现run方法,编写线程的执行体

创建线程对象,然后调用start方法启动线程

  test1 test = new test1();
  new Thread(test).start();
public class test1 implements Runnable {

    @Override
    public void run() {
        //run方法线程
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码");
        }
    }

    public static void main(String[] args) {
        //main主线程
        //创建线程对象
        test1 test = new test1();
        new Thread(test).start();

        //main主线程
        for (int j = 0; j < 20; j++) {
            System.out.println("我在学习线程");
        }

    }
}

区别

  • 继承Thread类

    子类去继承Thread类会具有多线程的能力,用子类对象:start()去启用线程,但是就会出现OOP单继承局限性

  • 实现Ruunable

​ 他也具有多线程能力,用传入目标对象+thread对象.start()去启用线程,他灵活方便,方便同一个对象被多给线程使用

未完~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值