业务对象(Business Object,BO)与数据传输对象(Data Transger Object, DTO)的区别:
1) 业务对象同时包含了数据和行为,是一个可以参与到领域逻辑中的完整对象。
2) DTO更像一种值对象,即一系列数据的容器而没有相关的行为。
3) 为了序列化,业务对象中的数据会复制到DTO中。
4) DTO并不仅仅是领域对象去掉了行为,它表示了特定领域对象的一个子集,用于专门的上下文中。例如,在某个方法中,Customer DTO或许仅需要公司名称和ID两个属性,而在另一个方法中,可能会需要ID、公司名称、国家和联系信息等。
5) 业务对象一个对象图,例如,Customer包含订单对象集合,而订单包含订单详细对象等。而DTO仅仅是所需要部分数据的投影而已。
6) DTO能减少层之间的耦合,使系统更加整洁干净。不过在实践中,为了避免增加DTO减少复杂性,DTO通常就是用业务对象替换。AsyncTask的本质是一个线程池,所有提交的异步任务都会在这个线程池中的工作线程内执行,当工作线程需要跟UI线程交互时,工作线程会通过向在UI线程创建的Handler(原理见:使用Thread+Handler实现非UI线程更新UI界面)传递消息的方式,调用相关的回调函数,从而实现UI界面的更新。
package com.lmw.android.test;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
public class AsyncTaskActivity extends Activity {
private ImageView mImageView;
private Button mButton;
private ProgressBar mProgressBar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asynctask);
mImageView= (ImageView) findViewById(R.id.asynctask_imageView);
mButton = (Button) findViewById(R.id.asynctask_download_btn);
mProgressBar = (ProgressBar) findViewById(R.id.asynctask_progressBar);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Task task = new Task();
task.execute("http://pic7.nipic.com/20100517/4945412_113951650422_2.jpg");
}
});
}
class Task extends AsyncTask<String,Integer,Bitmap> {//继承AsyncTask
@Override
protected Bitmap doInBackground(String... params) {//处理后台执行的任务,在后台线程执行
publishProgress(0);//将会调用onProgressUpdate(Integer... progress)方法
HttpClient hc = new DefaultHttpClient();
publishProgress(30);
HttpGet hg = new HttpGet(params[0]);//获取csdn的logo
final Bitmap bm;
try {
HttpResponse hr = hc.execute(hg);
bm = BitmapFactory.decodeStream(hr.getEntity().getContent());
} catch (Exception e) {
return null;
}
publishProgress(100);
//mImageView.setImageBitmap(result); 不能在后台线程操作ui
return bm;
}
protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用,在ui线程执行
mProgressBar.setProgress(progress[0]);//更新进度条的进度
}
protected void onPostExecute(Bitmap result) {//后台任务执行完之后被调用,在ui线程执行
if(result != null) {
Toast.makeText(AsyncTaskActivity.this, "成功获取图片", Toast.LENGTH_LONG).show();
mImageView.setImageBitmap(result);
}else {
Toast.makeText(AsyncTaskActivity.this, "获取图片失败", Toast.LENGTH_LONG).show();
}
}
protected void onPreExecute () {//在 doInBackground(Params...)之前被调用,在ui线程执行
mImageView.setImageBitmap(null);
mProgressBar.setProgress(0);//进度条复位
}
protected void onCancelled () {//在ui线程执行
mProgressBar.setProgress(0);//进度条复位
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/asynctask_progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ProgressBar>
<Button
android:id="@+id/asynctask_download_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下载图片" >
</Button>
<ImageView
android:id="@+id/asynctask_imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout> private static final int CORE_POOL_SIZE =5;//5个核心工作线程
private static final int MAXIMUM_POOL_SIZE = 128;//最多128个工作线程
private static final int KEEP_ALIVE = 1;//空闲线程的超时时间为1秒
private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10);//等待队列
private static final ThreadPoolExecutorsExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue,sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。
Task task = new Task();
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams);
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
Message message;
Result result = null;
try {
result = get();
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();//取消任务,发送MESSAGE_POST_CANCEL消息
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));//完成任务,发送MESSAGE_POST_RESULT消息并传递result对象
message.sendToTarget();
}
};
}task.execute("http://pic7.nipic.com/20100517/4945412_113951650422_2.jpg");public final AsyncTask<Params,Progress, Result> execute(Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw newIllegalStateException("Cannot execute task:"
+ " the taskis already running.");
case FINISHED:
throw newIllegalStateException("Cannot execute task:"
所谓素性测试是检测一个数是否为素数的测试。而对素数的研究是有很长一段历史,把素数的东西写成一本书的话也许得上千页,而现代密码学又加深了科研工作者对素数的研究,今天就以输出100以内的素数的为例,讲讲素性测试的几种方法。
这可能是每个学过计算机的朋友都敲过的代码,原理就是从判断2到sqrt(n)或者n/2能不能整除n,若能整除就不是素数。
代码清单:
public class SuXingCeShi {
public static void main(String[] args) {
int n = 100;
SuXingCeShi robot = new SuXingCeShi();
robot.shichu(n);
}
private void shichu(int n) {
for(int i = 2; i <= n; i++){
int j;
for(j = 2; j < Math.sqrt(i); j++){
if(i % j == 0)
break;
}
if(j > Math.sqrt(i))
System.out.print(i + " ");
}
System.out.println();
}
}2.eratosthenes筛选法(埃拉托斯特尼筛法)
步骤:
1.列出2,3,4..........100
2.选取第一个没被处理过的数(第一次为2)
3.去掉以2为因数的所有数
4.如果下一个素数小于sqrt(100)跳转到第二步
5.结束
以下是来至wikipedia介绍该算法的图片,挺直观的,可以看看
代码清单:
public class SuXingCeShi {
public static void main(String[] args) {
int n = 100;
SuXingCeShi robot = new SuXingCeShi();
robot.eratosthenesShaixuan(n);
}
public void eratosthenesShaixuan(int n) {
// TODO Auto-generated method stub
int[] a = new int[n+1];//申请n+1个空间
a[0] = a[1] = -1;//剔除0,1
for(int i = 2; i < n+1; i++)
a[i] = i;
int temp = 2;
double edge = Math.sqrt(n);//边界值
while(temp <= edge){
if(a[temp] == -1){//如果a[temp]是合数
temp++;
continue;
}
//如果a[temp]是质素,去掉以它为因数的合数
for(int i = 2; i <= (a.length-1)/temp ; i++){
a[temp*i] = -1;
}
temp++;
}
for(int i = 0; i < a.length; i++){
if(a[i] != -1)
System.out.print(a[i] + " ");
}
System.out.println();
}
}
3.一种更快的拆选算法
eratosthenes算法在拆选的时候进行了重复拆选,比如数30,2、3、5都对其进行了拆选,有没有一种更好的方法,让每个合数只被拆选一次呢?
这个算法稍稍有些难理解,先看代码
public class SuXingCeShi {
public static void main(String[] args) {
int n = 100;
SuXingCeShi robot = new SuXingCeShi();
robot.caixuan(n);
}
void caixuan(int n){
boolean flag[] = new boolean[n+1];
int prime[] = new int[n+1];
int prime_num = 0;
for(int i=0; i<=n; i++){
flag[i] = true;//把所有数都看成素数
}
for(int i = 2; i <= n; i++){
if(flag[i] == true){
prime[prime_num++] = i;//记录素数
}
for(int j=0; j <prime_num && prime[j]*i <= n; j++){
flag[prime[j]*i] = false;//把合数赋值成false
if(i % prime[j] == 0)
break;
}
}
for(int i = 0; i < prime.length; i++){
if(prime[i] != 0)
System.out.print(prime[i] + " ");
}
}
}我们先申请一个boolean[] flag来进行拆选,再申请一个int[] prime记录素数,在第二个for循环中进行判断,if(flag[i] == true)把它记录下来(因为我们把i之前的数都拆选过了,看二重for循环)比如现在
i = 9; i 前面的素数有2,3,5,7都记录在prime[]里了 然后遍历prime数组,j = 0时,flag[prime[j]*i] = false意思是把flag[2*9]
赋值成false,j = 1时候我们把flag[3*9] 赋值成false,关键是下面这句话,if(i % prime[j] == 0) break;它是整个算法的核心,为什么把flag[27]筛出去之后就不再筛flag[36]和flag[45]了呢?因为当i
= 18的时候 flag[2*18] 把flag[36]给筛出去了,但是没有筛选flag[3*18],flag[4*18] ,因为在flag[2*27]和flag[2*36]分别拆选过了。再举个例子比如i
= 35,当flag[2*35]拆选过后 ,还得筛选flag[3*35](假设n>105),因为flag[105]没法再由其他形式拆选了,所以用这样方式才保证了每个合数被筛选且仅被筛选一次。
4.wilson检测(威尔逊检测)
读过数论的朋友一定看过wilson算法,在数论中,威尔逊定理给出了判定一个自然是否为素数的充分必要条件,即:当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )
如果您没接触过数论,帮您解释下这个式子是啥意思,(mod p)叫同余 意思就是除以p后余数相等,可以把上述式子理解为当且仅当p为素数时,[(p-1)!+1]%p == 0
显然这个算法时间复杂度和需要数据类型的表示范围之大都是无法回避的,实际操作不可行,理论价值非常高。
代码清单:
public class SuXingCeShi {
public static void main(String[] args) {
int n = 100;
SuXingCeShi robot = new SuXingCeShi();
robot.wilson(n);
}
public void wilson(int n){
for(int i = 2; i <= n; i++)
if(isPrimeFromWilson(i))
System.out.print(i + " ");
System.out.println();
}
private boolean isPrimeFromWilson(int m) {
long temp = 1;
int i = m-1;
while(i >= 1){
temp *= i;
i--;
}
return (temp+1) % m == 0;
}
}
首先介绍一个数论中非常非常重要的一个定理-----费马小定理(费马很NB的,感兴趣的童鞋可以了解下)