android-java基础部分技能点

一面向对象

1.概念

    面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优化,操作起来更加的方便,简化了过程。面向对象有三大特征:封装性、继承性、多态性,其中封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。对于继承性,就是两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就 提高了代码的复用性。继承是作为多态的前提的。多态是说父类或接口的引用指向了子类对A象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性,但是多态有一点不好之处在于:父类引用不能访问子类中的成员。

    举例来说:就是:比如说你要去饭店吃饭,你只需要饭店,找到饭店的服务员,跟她说你要吃什么,然后叫会给你做出来让你吃,你并不需要知道这个饭是怎么错的,你只需要面向这个服务员,告诉他你要吃什么,然后他也只需要面向你吃完收到钱就好,不需要知道你怎么对这个饭进行吃。

2.特点

  • 将复杂的事情简单化
  • 面向对象将以前过程中的执行者,变为指挥官
  • 面向对象这种思想是符合现在人们思考习惯的一种思考习惯

3.特征

  1. 封装:隐藏对象的属性和实现细节,对外提供公共访问的方式
    好处:将变化隔离、便于使用、提高复用性、提高安全性
    原则:将不需要对外提供的内容隐藏起来;把属性隐藏,提供公共方法对其访问
  2. 继承:提高代码的复用性,继承是多态的前提
    子类中所有的构造函数都会默认访问父类中的空参数的构造函数,默认第一行有super();若无空参数构造函数,子类中需指定;另外,子类构造函数中可自己用this指定自身的其他构造函数。
  3. 多态:父类或接口定义的引用变量可以指向子类或具体实现类的实例对象
    好处:提高了程序的扩展性
    弊端:当父类引用指向子类对象时,虽提高了扩展性,但只能访问父类中具备的方法,不可访问子类中的方法;即访问的局限性。
    前提:实现或继承关系;覆写父类方法。

二 集合

    Java集合分为Collection和Map集合,如下图所示他们之间的关系,特点是长度可变,存储对象并且对象的类型可以不同


1.Collection

1.List
元素是有序的,可重复的,有索引

常用方法add(index, element)add(index, Collection)remove(index)set(index,element)get(index)subList(from, to)listIterator()

1)ArrayList:底层是数组结构,查询快,增删慢,不同步

2)LinkedList:底层是链表结构,增删快,查询慢,不同步

3)Vector:底层是数组结构,线程同步,被ArrayList取代了 

注:LinkedList对于元素判断是否存在,以及删除等操作,以依赖的方法是元素的hashCodeequals方法

ArrayList判断是否存在和删除操作依赖的是equals方法

2.Set

元素是无序的,不可重复,无索引

1)HashSet:底层是哈希表,线程不同步,无序,高效    

        保证元素唯一性:通过元素的hashCodeequals方法。若hashCode值相同,则会判断equals的结果是否为true ;hashCode不同,不会调用equals方法
    
LinkedHashSet:有序,是HashSet的子类

2)TreeSet:底层是二叉树,可对元素进行排序,默认是自然排序

    保证唯一性:Comparable接口的compareTo方法的返回值

  两种排序方式:两种都存在的话,以比较器为主

第一种:自然排序(默认排序)  添加的对象需要实现Comparable接口,覆盖compareTo方法

第二种:比较器        添加的元素自身不具备比较性或不是想要的比较方式。将比较器作为参数传递进去。

        定义一个类,实现Comparator接口,覆盖compare方法。当主要条件相同时,比较次要条件。

3.Map

1.类别

Java 自带了各种 Map 类。这些 Map 类可归为三种类型:

1) 通用Map,用于在应用程序中管理映射,通常在 java.util 程序包中实现

HashMap、Hashtable、Properties、LinkedHashMap、IdentityHashMap、TreeMap、WeakHashMap、ConcurrentHashMap

2) 专用Map,通常我们不必亲自创建此类Map,而是通过某些其他类对其进行访问

java.util.jar.Attributes、javax.print.attribute.standard.PrinterStateReasons、java.security.Provider、java.awt.RenderingHints、javax.swing.UIDefaults

3.)一个用于帮助我们实现自己的Map类的抽象类

    AbstractMap

2.类型区别
  1. HashMap
    最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许记录一条键为null;允许多条记录的值为null,非同步
  2. TreeMap
    能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。 
  3. HashTable
    与HashMap类似,不同的是:key和value的值不能为null;支持线程的同步,即任时刻只有一个线程能写HashTable,因此也导致了它写入慢。
  4. LinkedHashMap
    保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
3.常用方法

初始化 Map<String,String> map = new HashMap<String,String>();
插入元素  map.put("key","value");
获取元素  map.get("key");

移除元素  map.remove("key");

清空map  map.clear();

Map集合两种取出方式:

第一种:Set<K> keySet()

        取出Map集合中的所有键放于Set集合中,然后再通过键取出对应的值

Set<String> keySet= map.keySet();
Iterator<String>it = keySet.iterator();
while(it.hasNext()){
        String key = it.next();
        String value = map.get(key);
//…..
}

第二种:Set<Map.Entry<K,V>> entrySet()

        取出Map集合中键值对的映射放于Set集合中,然后通过Map集合中的内部接口,然后通过其中的方法取出

Set<Map.Entry<String,String>>entrySet = map.entrySet();
Iterator<Map.Entry<String,String>>it = entrySet.iterator();
While(it.hasNext()){
        Map.Entry<String,String> entry = it.next();
        String key = entry.getKey();
        String value = entry.getValue();
        //……
}


4.map遍历
  • 增强for循环遍历

    使用keySet()遍历

    Java |  复制
    1
    2
    3
    for  (String key : map.keySet()) {
         System.out.println(key +  " :"  + map.get(key));
    }

    使用entrySet()遍历

    Java |  复制
    1
    2
    3
    for  (Map.Entry<String, String> entry : map.entrySet()) {
         System.out.println(entry.getKey() +  " :"  + entry.getValue());
    }

  • 迭代器遍历

    使用keySet()遍历

    Java |  复制
    1
    2
    3
    4
    5
    Iterator<String> iterator = map.keySet().iterator();
    while  (iterator.hasNext()) {
         String key = iterator.next();
         System.out.println(key +  " :"  + map.get(key));
    }

    使用entrySet()遍历

    Java |  复制
    1
    2
    3
    4
    5
    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
    while  (iterator.hasNext()) {
         Map.Entry<String, String> entry = iterator.next();
         System.out.println(entry.getKey() +  " :"  + entry.getValue());
    }

5.Collection和Map的区别

Collection:单列集合,一次存一个元素

Map:双列集合,一次存一对集合,两个元素(对象)存在着映射关系

扩展 集合工具类

Collections:操作集合(一般是list集合)的工具类。方法全为静态的

sort(List list);list集合进行排序;sort(List list, Comparator c) 按指定比较器排序

fill(List list, T obj);将集合元素替换为指定对象

swap(List list, int I,int j)交换集合指定位置的元素

shuffle(List list); 随机对集合元素排序

reverseOrder() :返回比较器,强行逆转实现Comparable接口的对象自然顺序

三 IO流

结构如下图所示


Java中的流,可以从不同的角度进行分类。
按照数 据流的方向不同可以分为:输入流和输出流。
按照处理数据单位不同可以分为:字节流和字符流。
按照实现功能不同可以分为:节点流和处理流。
输出流:
 
输入流:

因此输入和输出都是从程序的角度来说的。
字节流:一次读入或读出是 8 位二进制。
字符流:一次读入或读出是 16 位二进制。
字节流和字符流的原理是相同的,只不过处理的单位不同而已。后缀是 Stream 是字节流,而后缀是 Reader Writer 是字符流。


1.字符流

1)Reader:读取字符流的抽象类

        BufferedReader:将字符存入缓冲区,再读取

        LineNumberReader:带行号的字符缓冲输入流

      InputStreamReader:转换流,字节流和字符流的桥梁,多在编码的地方使用

        FileReader:读取字符文件的便捷类。

2)Writer:写入字符流的抽象类

      BufferedWriter:将字符存入缓冲区,再写入

     OutputStreamWriter:转换流,字节流和字符流的桥梁,多在编码的地方使用

     FileWriter:写入字符文件的便捷类。

2.字节流

3)InputStream:字节输入流的所有类的超类

     ByteArrayInputStream:含缓冲数组,读取内存中字节数组的数据,未涉及流

      FileInputStream:从文件中获取输入字节。媒体文件

      BufferedInputStream:带有缓冲区的字节输入流

       DataInputStream:数据输入流,读取基本数据类型的数据

       ObjectInputStream:用于读取对象的输入流

      PipedInputStream:管道流,线程间通信,与PipedOutputStream配合使用

      SequenceInputStream:合并流,将多个输入流逻辑串联。

4) OutputStream:此抽象类是表示输出字节流的所有类的超类

       ByteArrayOutputStream:含缓冲数组,将数据写入内存中的字节数组,未涉及流

        FileOutStream:文件输出流,将数据写入文件

        BufferedOutputStream:带有缓冲区的字节输出流

        PrintStream:打印流,作为输出打印

        DataOutputStream:数据输出流,写入基本数据类型的数据

        ObjectOutputStream:用于写入对象的输出流

      PipedOutputStream:管道流,线程间通信,与PipedInputStream配合使用

3.流操作规律

        明确源和目的:

                数据源:读取,InputStreamReader

                目的:写入:OutStreamWriter

        数据是否是纯文本:

                是:字符流,ReaderWriter

                否:字节流,InputStreamOutStream

        明确数据设备:

                源设备:内存、硬盘、键盘

                目的设备:内存、硬盘、控制台

        是否提高效率:用BufferedXXX

4.转换流:将字节转换为字符,可通过相应的编码表获得

        转换流都涉及到字节流和编码表

四 多线程

1.进程和线程

    进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位

    线程是进度的一个实体,是cpu调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

关系:

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

2.创建线程的方式

创建方式一:继承Thread

  1. 定义一个类继承Thread
  2. 覆盖Thread中的run方法(将线程运行的代码放入run方法中)。
  3. 直接创建Thread的子类对象
  4. 调用start方法(内部调用了线程的任务(run方法));作用:启动线程,调用run方法
new Thread(){
public void run(){
   //TODO
   }
}.start();

方式二:实现Runnable

  1. 定义类实现Runnable
  2. 覆盖Runnable接口中的run方法,将线程的任务代码封装到run中
  3. 通过Thread类创建线程对象
  4. 并将Runnable接口的子类对象作为Thread类的构造函数参数进行传递作为参数传递的原因是让线程对象明确要运行的run方法所属的对象。

区别:

        继承方式:线程代码放在Thread子类的run方法中

        实现方式:线程存放在接口的子类run方法中;避免了单继承的局限性,建议使用。

3.线程状态


新建:start()

临时状态:具备cpu的执行资格,但是无执行权

运行状态:具备CPU的执行权,可执行

冻结状态:通过sleep或者wait使线程不具备执行资格,需要notify唤醒,并处于临时状态。

消亡状态:run方法结束或者中断了线程,使得线程死亡。

4.多线程安全问题

多个线程共享同一数据,当某一线程执行多条语句时,其他线程也执行进来,导致数据在某一语句上被多次修改,执行到下一语句时,导致错误数据的产生。

因素:多个线程操作共享数据;多条语句操作同一数据

解决:

        原理:某一时间只让某一线程执行完操作共享数据的所有语句。

        办法:使用锁机制:synchronizedlock对象

5.线程的同步

当两个或两个以上的线程需要共享资源,他们需要某种方法来确定资源在某一刻仅被一个线程占用,达到此目的的过程叫做同步(synchronization)。

同步代码块:synchronized(对象){},将需要同步的代码放在大括号中,括号中的对象即为锁。

同步函数:放于函数上,修饰符之后,返回类型之前。

6.waitsleep的区别:(执行权和锁区分)

wait:可指定等待的时间,不指定须由notifynotifyAll唤醒。

        线程会释放执行权,且释放锁。

sleep:必须指定睡眠的时间,时间到了自动处于临时(阻塞)状态。

        即使睡眠了,仍持有锁,不会释放执行权。

五 常用的设计模式

1.单例模式

所谓单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类(Singleton类)永远只会有一个实例化对象产生。具体实现步骤如下:

      (1) 将采用单例设计模式的类的构造方法私有化(采用private修饰)。

      (2) 在其内部产生该类的实例化对象,并将其封装成private static类型。

      (3) 定义一个静态方法返回该类的实例。

实现方式
/**  
 *   
 * 单例模式的实现:饿汉式,线程安全 但效率比较低  
 */  
public class SingletonTest {   
  
    private SingletonTest() {   
    }   
  
    private static final SingletonTest instance = new SingletonTest();   
  
    public static SingletonTest getInstancei() {   
        return instance;   
    }   
  
} 
/**  
 * 单例模式的实现:懒汉式,非线程安全   
 *   
 */  
public class SingletonTest {   
    private SingletonTest() {   
    }   
  
    private static SingletonTest instance;   
  
    public static SingletonTest getInstance() {   
        if (instance == null)   
            instance = new SingletonTest();   
        return instance;   
    }   
}

/**  
 * 线程安全,但是效率非常低  
 * @author vanceinfo  
 *  
 */  
public class SingletonTest {   
    private SingletonTest() {   
    }   
  
    private static SingletonTest instance;   
  
    public static synchronized SingletonTest getInstance() {   
        if (instance == null)   
            instance = new SingletonTest();   
        return instance;   
    }
/**  
 * 线程安全  并且效率高  
 *  
 */  
public class SingletonTest {   
    private static SingletonTest instance;   
  
    private SingletonTest() {   
    }   
  
    public static SingletonTest getIstance() {   
        if (instance == null) {   
            synchronized (SingletonTest.class) {   
                if (instance == null) {   
                    instance = new SingletonTest();   
                }   
            }   
        }   
        return instance;   
    }   
}  


2.工厂设计模式

程序在接口和子类之间加入了一个过渡端,通过此过渡端可以动态取得实现了共同接口的子类实例化对象。

      示例代码如下:

interface Animal { // 定义一个动物的接口  
    public void say(); // 说话方法  
}   
  
class Cat implements Animal { // 定义子类Cat  
    @Override  
    public void say() { // 覆写say()方法  
        System.out.println("我是猫咪,喵呜!");   
    }   
}   
  
class Dog implements Animal { // 定义子类Dog  
  
    @Override  
    public void say() { // 覆写say()方法  
        System.out.println("我是小狗,汪汪!");   
    }   
}   
  
class Factory { // 定义工厂类  
    public static Animal getInstance(String className) {   
        Animal a = null; // 定义接口对象  
        if ("Cat".equals(className)) { // 判断是哪个子类的标记  
            a = new Cat(); // 通过Cat子类实例化接口  
        }   
        if ("Dog".equals(className)) { // 判断是哪个子类的标记  
            a = new Dog(); // 通过Dog子类实例化接口  
        }   
        return a;   
    }   
}   
  
public class FactoryDemo {   
  
    public static void main(String[] args) {   
        Animal a = null; // 定义接口对象  
        a = Factory.getInstance(args[0]); // 通过工厂获取实例  
        if (a != null) { // 判断对象是否为空  
            a.say(); // 调用方法   
        }   
    }   
}  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值