知识点梳理2 Java 基础

2018-07-26  本文已影响13人  48d1753082c0

Lambda

原生版

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText( MainActivity.this,"AAA",Toast.LENGTH_SHORT ).show();
            }
});

Lambda 版

button.setOnClickListener(v -> Toast.makeText( MainActivity.this,"AAA",Toast.LENGTH_SHORT ).show());
(parameters) -> { expression or statements }
// 无参数, 返回1+2的结果 
() -> 1+2  
  
// 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x
  
// 接收2个参数(数字),返回表达式运算的结果 
(x, y) -> x + y

// 多个语句要用大括号包裹, 并且返回值要用return指明
(x, y) -> {
    int result = x + y;
    System.out.print(result);
    return result;
}
  
// 接收string 对象, 并在控制台打印 
s -> System.out.print(s)
其中参数的类型可以不声明, 编译器会结合上下文智能推断, 比如这句

s -> System.out.print(s)
等价于

(String s) -> System.out.print(s)
注意: 无参数时()不能省略

lambda 的应用场景:
单实现的接口
条目点击事件
封装网络请求的回调
与RxJava的链式调用

1.view.setOnClickListener(v -> {
            //dosomething
        });

2.  listview.setOnItemClickListener((parent, view, position, id) -> {
            //dosomething
});  

3.例如通过封装OkHttp或者Retrofit的回调方法,将其转变成单实现的回调接口进行调用  

4.Integer[] list = {1,2,3,4,5};
Observable
    .from(list)
    .filter(integer->integer%2==0)//挑选出偶数
    .map(integer -> "number is"+integer)//转换成String
    .subscribe(s->System.out.println(s));//相当于forEach(s->System.out.println(s));
    //forEach是同步的 subscribe是异步的

参考:https://www.jianshu.com/p/a3fd8e063f27

泛型

// 泛型类:把泛型定义在类上 
public class ObjectTool<T> { 
      private T obj; 
      public T getObj() { 
         return obj; 
      } 
      public void setObj(T obj) { 
           this.obj = obj;
     }
}

// 泛型方法:把泛型定义在方法上
public class ObjectTool {
      public <T> void show(T t) {
           System.out.println(t); 
      }
}

/* * 泛型接口:把泛型定义在接口上 */
public interface Inter<T> { 
  public abstract void show(T t);
}
List<String>[] ls = new ArrayList<String>[10];//编译报错
List<String>[] list = new ArrayList[10];//正确
List<?>[] ls = new ArrayList<?>[10];//正确

泛型学习的基础文章:

设计模式

1.单一职责原则(Single Responsibility Principle, SRP)
定义:一个类应只包含单一的职责。
2.开放封闭原则(Open - Closed Principle, OCP)
定义:一个模块、类、函数应当是对修改关闭,扩展开放。
3.里氏代换原则( Liskov Substitution Principle, LSP)
定义:使用父类的地方能够使用子类来替换,反过来,则不行。
4.依赖倒转原则( Dependence Inversion Principle, DIP)
定义:抽象不应该依赖于细节,细节应当依赖于抽象。
5.接口隔离法则(Interface Segregation Principle, ISL)
定义:一个类对另一个类的依赖应该建立在最小的接口上。
6.迪米特法则(Law of Demeter, LoD)
定义:一个类尽量不要与其他类发生关系

设计模式一般分为三类:创建型模式、结构型模式、行为型模式。

创建型模式

创建型模式简单来说就是用来创建对象的。一共有五种:单例模式、建造者模式、工厂方法模式、抽象工厂模式、原型模式。
单例模式 :确保某一个类只有一个实例,并且提供一个全局访问点。
建造者模式 : 用来创建复杂的复合对象。
工厂方法模式 :让子类来决定要创建哪个对象。
抽象工厂模式 :创建多个产品族中的产品对象。
原型模式 :通过复制原型来创建新对象。

行为型模式

行为型模式主要是描述类或者对象是怎样交互和怎样分配职责的。一共有十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
策略模式 :封装不同的算法,算法之间能互相替换。
状态模式 :根据不同的状态做出不同的行为。
责任链模式 :将事件沿着链去处理。
观察者模式 :状态发生改变时通知观察者,一对多的关系。
模板方法模式 :定义一套流程模板,根据需要实现模板中的操作。
迭代器模式 :提供一种方法顺序访问一个聚合对象中的各个元素。
备忘录模式 :保存对象的状态,在需要时进行恢复。
访问者模式 :稳定数据结构中,定义新的操作行为。
中介者模式 :将网状结构转变为星型结构,所有行为都通过中介。
解释器模式 :定义语法,并对其进行解释。
命令模式 :将请求封装成命令,并记录下来,能够撤销与重做。

结构型模式

结构型模式主要是用于处理类或者对象的组合。一共有七种:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
代理模式 :控制客户端对对象的访问。
组合模式 :将整体与局部(树形结构)进行递归组合,让客户端能够以一种的方式对其进行处理。
适配器模式 :将原来不兼容的两个类融合在一起。
装饰者模式 :为对象添加新功能。
享元模式 :使用对象池来减少重复对象的创建。
外观模式 :对外提供一个统一的接口用来访问子系统。
桥接模式 :将两个能够独立变化的部分分离开来。

参考:https://www.jianshu.com/p/a3e844619ed2

单例:

public class Singleton {
    private volatile static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

public class Singleton {

    private Singleton() {
    }

    public static Singleton getSingleton() {
        return SingletonHolder.sInstance;
    }
    
    private static class SingletonHolder {
        private static final Singleton sInstance = new Singleton();
    }
}

使用反射能够破坏单例模式,所以应该慎用反射
可以通过当第二次调用构造函数时抛出异常来防止反射破坏单例,以懒汉式为例:
反序列化时也会破坏单例模式,可以通过重写readResolve方法避免,以饿汉式为例:

建造者:

image.png

Android中的源码分析
Android中的AlertDialog.Builder就是使用了Builder模式来构建AlertDialog的。

AlertDialog.Builder的简单用法

        AlertDialog.Builder builder = new AlertDialog.Builder(activity);//创建一个Builder对象
        builder.setIcon(R.drawable.icon);
        builder.setTitle("标题");
        builder.setMessage("信息");
        builder.setPositiveButton("确定",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
        AlertDialog alertDialog = builder.create();//创建AlertDialog对象
        alertDialog.show();//展示AlertDialog

通过Builder对象来构建Icon、Title、Message等,将AlertDialog的构建过程和细节隐藏了起来。

AlertDialog相关源码分析

//AlertDialog源码
public class AlertDialog extends Dialog implements DialogInterface {
    private AlertController mAlert;//接受Builder成员变量P的参数

    AlertDialog(Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
        super(context, createContextThemeWrapper ? resolveDialogTheme(context, themeResId) : 0, createContextThemeWrapper);
        mWindow.alwaysReadCloseOnTouchAttr();
        mAlert = AlertController.create(getContext(), this, getWindow());//创建AlertController对象
    }

    @Override
    public void setTitle(CharSequence title) {//设置Title
        super.setTitle(title);
        mAlert.setTitle(title);//保存在AlertController对象中
    }

    public void setMessage(CharSequence message) {//设置Message
        mAlert.setMessage(message);//保存在AlertController对象中
    }

    public void setIcon(@DrawableRes int resId) {//设置Icon
        mAlert.setIcon(resId);//保存在AlertController对象中
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAlert.installContent();//安装AlertDialog的内容
    }

    //AlertDialog其他代码略

    public static class Builder {
        private final AlertController.AlertParams P;//构建AlertDialog对象所需要的参数都存放在P中

        public Builder(Context context) {
            this(context, resolveDialogTheme(context, 0));
        }

        public Builder(Context context, int themeResId) {
            P = new AlertController.AlertParams(new ContextThemeWrapper(
                    context, resolveDialogTheme(context, themeResId)));//初始化AlertParams对象
        }

        public Context getContext() {
            return P.mContext;
        }

        public android.app.AlertDialog.Builder setTitle(CharSequence title) {
            P.mTitle = title;//保存title到P中
            return this;
        }

        public android.app.AlertDialog.Builder setMessage(CharSequence message) {
            P.mMessage = message;//保存message
            return this;
        }


        public android.app.AlertDialog.Builder setIcon(@DrawableRes int iconId) {
            P.mIconId = iconId;//保存IconId
            return this;
        }

        //Builder其他代码略

        public android.app.AlertDialog create() {//构建AlertDialog
            final android.app.AlertDialog dialog = new android.app.AlertDialog(P.mContext, 0, false);//创建一个AlertDialog对象
            P.apply(dialog.mAlert);//将P中的参数设置到AlertController中
            //其他设置代码略
            return dialog;
        }
    }
}
//Dialog源码
 public class Dialog implements DialogInterface, Window.Callback, KeyEvent.Callback, View.OnCreateContextMenuListener, Window.OnWindowDismissedCallback {
        //其他代码略
        public void show() {
            //前面代码略
            if (!mCreated) {
                dispatchOnCreate(null);//分发onCreate
            } else {
                final Configuration config = mContext.getResources().getConfiguration();
                mWindow.getDecorView().dispatchConfigurationChanged(config);
            }

            onStart();//调用onStart()
            mDecor = mWindow.getDecorView();
            
            //设置参布局参数略
           
            mWindowManager.addView(mDecor, l);//添加到WindowManager
            mShowing = true;

            sendShowMessage();
        }
        
        void dispatchOnCreate(Bundle savedInstanceState) {//分发onCreate
            if (!mCreated) {
                onCreate(savedInstanceState);//调用AlertDialog的onCreate方法,创建AlertDialog视图
                mCreated = true;
            }
        }
    }
//AlertController源码
public class AlertController {
        //其他代码略

        public void installContent() {//安装内容
            int contentView = selectContentView();//选择合适的布局
            mWindow.setContentView(contentView);//布局添加到Window中
            setupView();//把dialog.mAlert对象中需要构建的元素逐个添加设置到Window上,即构建我们设置的布局发生在这一步中
        }
    }

简单流程说明:

1.通过AlertDialog.Builder设置各种属性后(如:setTitle()),这些属性信息会保存在P变量中,P变量的类型为AlertController.AlertParams。

2.调用builder.create()即可返回一个AlertDialog对象。
2.1 builder.create()方法中首先会创建一个AlertDialog对象,AlertDialog对象构造时会初始化WindowManager和Window。
2.2 builder.create()创建完AlertDialog对象后,会调用 P.apply(dialog.mAlert);即把P变量中所存储的用来构建AlertDialog对象的元素设置到了dialog.mAlert中,dialog.mAlert的类型为AlertController。

3.调用AlertDialog的show()方法,展示界面。
3.1 show()方法中会调用 dispatchOnCreate(null),dispatchOnCreate(null)调起onCreate(),onCreate()会调起mAlert.installContent();即安装AlertDialog的内容。
3.2 installContent()中会调用mWindow.setContentView(mAlertDialogLayout);即把mAlertDialogLayout这个布局加到Window中去。
3.3 调完mWindow.setContentView(mAlertDialogLayout)后会调用setupView(),setupView()中会把dialog.mAlert对象中需要构建的元素逐个添加设置到mWindow上。
3.4 最后通过把view添加到mWindowManager上展示出来。

总结:
builder模式隐藏了这种复杂的构建过程,只需几行简单的代码就把AlertDialog给展示出来了。
AlertDialog的builder中并没有抽象建造者(Builder)、Director(指挥者类)等角色。AlertDialog.Builder同时扮演了Builder、ConcreteBuilder、Director等角色,这是Android中的一种简化,也值得我们去学习使用。

参考:https://www.jianshu.com/p/154948d5adc6

工厂方法:


image.png

Android中的源码分析
Android中的ThreadFactory就是使用了工厂方法模式来生成线程的,线程就是ThreadFactory的产品。

ThreadFactory相关源码分析
//抽象产品:Runnable
public interface Runnable {
public abstract void run();
}

//具体产品:Thread
public class Thread implements Runnable {
    //构造方法
    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }
    
    @Override
    //实现抽象产品的抽象方法
    public void run() {
        if (target != null) {
            target.run();
        }
    }
    
    //其他代码略
}


//抽象工厂:ThreadFactory
public interface ThreadFactory {
    Thread newThread(Runnable r);
}

//具体工厂:AsyncTask中的实现
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
    private final AtomicInteger mCount = new AtomicInteger(1);
    
    //实现抽象工厂的抽象方法
    public Thread newThread(Runnable r) {
        return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());//返回Thread这个产品
    }
};

总结:
这里只要是介绍Android系统中工厂方法模式的应用,线程和AsyncTask的原理就不说了。
通过ThreadFactory,我们可以创建出不同的Thread来。
同样,我们可以创建另外类似的工厂,生产某种专门的线程,非常容易扩展。

参考:https://www.jianshu.com/p/e6c02a54f447

上一篇下一篇

猜你喜欢

热点阅读