java当中单例模式用得非常的多,那么今天我就讲一讲具体的单例模式把!
废话不多说!直接贴代码:
1.先看第一种单例模式,也是最简单的了:
很简单,这么想,就是穷屌丝和高富帅的区别,高富帅,一生下来就什么 都有了。
package com.lamp.demo;
/**
* 单例模式设计思想【这种效率好【因为没加锁】】
*
* @author fei
* @打个比方,高富帅和穷屌丝的区别
*/
public class Singleton2 {
private static Singleton2 instance = new Singleton2();
private Singleton2() {
}
public static Singleton2 getInstance() {
return instance;
}
// 加成员方法
}
2.第二种单例模式,是加了同步代码块的,但是失去了效率:
package com.lamp.demo;
/**
* 单例设计模式 线程安全的
*
* @author fei
*
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
// 为了线程安全,加了一把锁,但是失去了效率
public synchronized static Singleton getSingleton() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
public void sayHello(String string) {
System.out.println("Hello " + string);
}
}
3.第三种,据说是最牛的!在android中,运用的非常广泛哦,比如一个listview加载一个baseadapter,那么就需要用到这种设计模式。可以有效的提高app的性能。
package com.lamp.demo;
/**
* 最牛逼的单例模式 设计者----Bob Lee----【google】
*
* @author fei
* 利用了类的加载机制【】
*/
public class Foo {
static class Holder {
static Foo instance = new Foo();
}
public static Foo getSingleton() {
return Holder.instance;
}
private Foo() {
System.out.println("实例化");
}
public static void main(String[] args) {
Foo foo = Foo.getSingleton();
}
}
那么我们来看一下,安卓中的具体运用把
package com.soul.listview;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
//通过适配器加载其他布局组件的listView,并优化性能之
public class MainActivity5 extends Activity {
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main5);
lv = (ListView) findViewById(R.id.listView1);
// 通过适配器连接数据组件
lv.setAdapter(new MyAadapter());
}
// 定义数据
private int[] images = { R.drawable.ic_launcher, R.drawable.ic_launcher };
private String[] names = { "小花", "小黄" };
// 自定义适配器
class MyAadapter extends BaseAdapter {
// 1.获取列表项的总数
@Override
public int getCount() {
return names.length;
}
// 2.获取每一个列表项【根据位置】
@Override
public Object getItem(int position) {
return names[position];
}
// 3.获取每一个列表项的id【根据位置】
@Override
public long getItemId(int position) {
return position;
}
// 4.返回一个view布局【关键方法哦】
// 不适合调用大数据的布局组件,【因为你在不停滑动的时候会不停的去调用,创建N个对象出来】
// 你可以打印出view地址来看看,发现每一个地址都不一样【虽然有垃圾回收机制,但是回收哪有这么快嘛。所以内存会溢出的】
// 所以我们应该优化它哦。2次优化步骤:
// a.重复使用convertView
// b.使用ViewHolder提高在容器中查找组件的效率
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 打印看看到底是什么
System.out.println("position=" + position);
System.out.println("convertView=" + convertView);
System.out.println("---------------");
// 4.1.创建一个view通过填充器填充布局
// View view = getLayoutInflater().inflate(R.layout.main5_item,
// null);
// a.开始优化咯。用a方法[把创建的View直接换成convertView【第一次生成的时候是null】]
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.main5_item,
null);
// b-2.第一次通过convertView找到布局组件,存在保持器中
ViewHolder vh = new ViewHolder();
vh.iv = (ImageView) convertView.findViewById(R.id.imageView1);
vh.tv = (TextView) convertView.findViewById(R.id.textView1);
// b-4.赋值
vh.iv.setImageResource(images[position]);
vh.tv.setText(names[position]);
// b-3.然后把这个保持器存起来,存放在一个标签当中。
convertView.setTag(vh);
} else {
// b-4.只要第一次找到之后,我们就可以直接从convertView中的标签中拿出布局组件来.然后就可以填充资源了
ViewHolder vh = (ViewHolder) convertView.getTag();
vh.iv.setImageResource(images[position]);
vh.tv.setText(names[position]);
}
System.out.println(convertView);
// 4.2.得到自定义的布局组件
// ImageView iv = (ImageView) convertView
// .findViewById(R.id.imageView1);
// TextView tv = (TextView)
// convertView.findViewById(R.id.textView1);
// 4.3.开始填充资源
// iv.setImageResource(images[position]);
// tv.setText(names[position]);
return convertView;
}
}
// b-1.自定义一个ViewHolder类把这2个组件hold住。存起来
// 然后开始利用这个类
// 使用静态内部类效率又更高点哦
static class ViewHolder {
ImageView iv;
TextView tv;
}
}