热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Retrifit2.0

Retrofit2.0使用详解Retrofit2.0使用详解标签: androidretrofit网络2016-04-0301:09 39079人阅读 评论(16) 收藏 举报标签
  Retrofit2.0使用详解
标签: androidretrofit网络
技术分享 分类:
 

目录(?)[+]

 

综述

  retrofit是由square公司开发的。square在github上发布了很多优秀的Android开源项目。例如:otto(事件总线),leakcanary(排查内存泄露),android-times-square(日历控件),dagger(依赖注入),picasso(异步加载图片),okhttp(网络请求),retrofit(网络请求)等等。更多square上的开源项目我们可以去square的GitHub进行查看。这次就来介绍一下retrofit的一些基本用法。retrofit是REST安卓客户端请求库。使用retrofit可以进行GET,POST,PUT,DELETE等请求方式。下面就来看一下retrofit的基本用法。

Retrofit使用方法

  由于retrofit2.0与先前版本的差别还是比较大,对于不同版本之间的差异在这里就不在进行详细区别。下面的例子也是针对于retrofit2.0进行介绍的。retrofit2.0它依赖于OkHttp,而且这部分也不再支持替换。在这里我们也不需要显示的导入okHttp,在retrofit中已经导入okhttp3。


  com.squareup.okhttp3
  mockwebserver
  test
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

  在下面的例子当中采用与GitHub一些相关api进行演示。在这里首先需要添加访问网络的权限。

"android.permission.INTERNET"/>
  • 1
  • 1

简单示例

添加Gradle依赖项

  在这里我们最好查看一下retrofit的官网添加最新依赖。

compile ‘com.squareup.retrofit2:retrofit:2.0.1‘
  • 1
  • 1

创建API接口

  在retrofit中通过一个Java接口作为http请求的api接口。

public interface GitHubApi {

    @GET("repos/{owner}/{repo}/contributors")
    Call contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

创建retrofit实例

  在这里baseUrl是在创建retrofit实力的时候定义的,我们也可以在API接口中定义完整的url。在这里建议在创建baseUrl中以”/”结尾,在API中不以”/”开头和结尾。

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .build();
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

调用API接口

  在调用API接口请求后,获得一个json字符串,通过Gson进行解析,获得login以及contributions。

GitHubApi repo = retrofit.create(GitHubApi.class);

    Call call = repo.contributorsBySimpleGetCall(mUserName, mRepo);
call.enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
        try {
            Gson gson = new Gson();
            ArrayList cOntributorsList= gson.fromJson(response.body().string(), new TypeToken>(){}.getType());
            for (Contributor contributor : contributorsList){
                Log.d("login",contributor.getLogin());
                Log.d("contributions",contributor.getContributions()+"");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(Call call, Throwable t) {

    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

效果展示

  这样就完成了一个http请求,上面请求的完整地址为:https://api.github.com/repos/square/retrofit/contributors 
  然后我们看一下运行结果: 
技术分享

取消请求

  我们可以终止一个请求。终止操作是对底层的httpclient执行cancel操作。即使是正在执行的请求,也能够立即终止。

call.cancel();
  • 1
  • 1

转换器

  在上面的例子中通过获取ResponseBody后,我们自己使用Gson来解析接收到的Json格式数据。在Retrofit中当创建一个Retrofit实例的时候可以为其添加一个Json转换器,这样就会自动将Json格式的响应体转换为所需要的Java对象。那么先来看一下如何根据已有的Json格式数据如何生成Java对象。当然我们可以根据已知的数据手动创建Java对象,也可以通过工具更具Json格式为我们自动生成Java对象。

自动生成Java对象

  在这里介绍两种根据Json数据自动生成Java对象的工具。

jsonschema2pojo

  可以通过访问jsonschema2pojo网站。先来看一下它的使用方法。 
技术分享
  上面配置中所选注解若是使用的Gson解析,可以选择Gson,当然没有也是可以的。对于@Generated注解若是需要保留的话添加如下依赖,也可以直接删除@Generated注解,没有任何影响。

compile ‘org.glassfish:javax.annotation:10.0-b28‘
  • 1
  • 1

GsonFormat

  GsonFormat是AndroidStudio中的一个插件,在AndroidStudio的插件选项中直接搜索安装这个插件即可。在这里看一下是如何使用这个插件的。 
技术分享

添加转换器

  在这里我们需要为retrofit添加gson转换器的依赖。添加过converter-gson后不用再添加gson库。在converter-gson中已经包含gson。

compile ‘com.squareup.retrofit2:converter-gson:2.0.1‘
  • 1
  • 1

  在这里先创建一个Java类Contributor,用来保存接收到的数据。

public class Contributor {
    private String login;
    private Integer contributions;

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public Integer getContributions() {
        return contributions;
    }

    public void setContributions(Integer contributions) {
        this.cOntributions= contributions;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

  这时候修改我们的API接口。

@GET("repos/{owner}/{repo}/contributors")
Call> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo);
  • 1
  • 2
  • 1
  • 2

  创建retrofit实例,我们通过addConverterFactory指定一个factory来对响应反序列化,在这里converters被添加的顺序将是它们被Retrofit尝试的顺序。

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  调用上面所修改的API接口。

GitHubApi repo = retrofit.create(GitHubApi.class);
Call> call = repo.contributorsByAddConverterGetCall(mUserName, mRepo);
call.enqueue(new Callback>() {
    @Override
    public void onResponse(Call> call, Response> response) {
        List cOntributorList= response.body();
        for (Contributor contributor : contributorList){
            Log.d("login", contributor.getLogin());
            Log.d("contributions", contributor.getContributions() + "");
        }
    }

    @Override
    public void onFailure(Call> call, Throwable t) {

    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

  最后在来看一下运行结果。 
技术分享
  retrofit不仅仅只支持gson,还支持其他许多json解析库。以下版本号需要与retrofit版本号保持一致,并且以retrofit官网给出的版本号为准。

  • Gson: compile ‘com.squareup.retrofit2:converter-gson:2.0.1‘
  • Jackson: compile ‘com.squareup.retrofit2:converter-jackson:2.0.1‘
  • Moshi: compile ‘com.squareup.retrofit2:converter-moshi:2.0.1‘
  • Protobuf: compile ‘com.squareup.retrofit2:converter-protobuf:2.0.1‘
  • Wire: compile ‘com.squareup.retrofit2:converter-wire:2.0.1‘
  • Simple XML: compile ‘com.squareup.retrofit2:converter-simplexml:2.0.1‘
  • Scalars (primitives, boxed, and String):compile ‘com.squareup.retrofit2:converter-scalars:2.0.1‘

增加日志信息

  在retrofit2.0中是没有日志功能的。但是retrofit2.0中依赖OkHttp,所以也就能够通过OkHttp中的interceptor来实现实际的底层的请求和响应日志。在这里我们需要修改上一个retrofit实例,为其自定自定义的OkHttpClient。代码如下:

HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(httpLoggingInterceptor)
        .build();

Retrofit retrofit = new Retrofit.Builder().addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .client(okHttpClient)
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  还需要添加如下依赖。

compile ‘com.squareup.okhttp3:logging-interceptor:3.1.2‘
  • 1
  • 1

  其他代码没有任何变化,我们来看一下运行结果。 
技术分享

添加请求头

  我们可以通过@Headers来添加请求头。

@Headers({
        "Accept: application/vnd.github.v3.full+json",
        "User-Agent: RetrofitBean-Sample-App",
        "name:ljd"
})
@GET("repos/{owner}/{repo}/contributors")
Call> contributorsAndAddHeader(@Path("owner") String owner,@Path("repo") String repo);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  运行结果。 
技术分享

同步请求

  在这里我们可以直接通过call.execute()执行一个同步请求,由于不允许在主线程中进行网络请求操作,所以我们需要再子线程中进行执行。

new Thread(new Runnable() {
    @Override
    public void run() {

        try {
            Response> respOnse= call.execute();
            List cOntributorsList= response.body();
            for (Contributor contributor : contributorsList){
                Log.d("login",contributor.getLogin());
                Log.d("contributions",contributor.getContributions()+"");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

  在这里看一下运行结果。 
技术分享

clone

  在这里无论是同步操作还是异步操作每一个call对象实例只能被执行一次。多次执行抛出如下异常。 
技术分享
  在这里如果我们的request和respone都是一一对应的。我们通过Clone方法创建一个一模一样的实例,并且它的开销也是很小的。

Call> clOneCall= call.clone();
cloneCall.execute();

get请求

  在前面的一些例子当中我们都是采用get请求。当然我们也可以为URL指定查询参数。使用@Query即可。

@GET("search/repositories")
Call queryRetrofitByGetCall(@Query("q")String owner,
                                      @Query("since")String time,
                                      @Query("page")int page,
                                      @Query("per_page")int per_Page);

参数过多的时候我们可以通过@QueryMap注解和map对象参数来指定每个表单项的Key,value的值。

@GET("search/repositories")
Call queryRetrofitByGetCallMap(@QueryMap Map map);

  下面的call对象实例为上面api中所返回call对象。更具所返回的json数据所创建的实体类在这里就不在贴出代码,下载源码详细查看。

call.enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
        RetrofitBean retrofit = response.body();
        List list = retrofit.getItems();
        if (list == null)
            return;
        Log.d(TAG, "total:" + retrofit.getTotalCount());
        Log.d(TAG, "incompleteResults:" + retrofit.getIncompleteResults());
        Log.d(TAG, "----------------------");
        for (Item item : list) {
            Log.d(TAG, "name:" + item.getName());
            Log.d(TAG, "full_name:" + item.getFull_name());
            Log.d(TAG, "description:" + item.getDescription());
            Owner owner = item.getOwner();
            Log.d(TAG, "login:" + owner.getLogin());
            Log.d(TAG, "type:" + owner.getType());
        }

    }

    @Override
    public void onFailure(Call call, Throwable t) {

    }
});

  上面请求中的完整连接为: https://api.github.com/search/repositories?q=retrofit&since=2016-03-29&page=1&per_page=3,运行结果如下。 
技术分享

  在Retrofit 2.0添加了一个新的注解:@Url,它允许我们直接传入一个请求的URL。这样以来我们可以将上一个请求的获得的url直接传入进来。方便了我们的操作。

@GET
Call> repoContributorsPaginate(@Url String url);

Form encoded和Multipart

Form encoded

  我们可以使用@FormUrlEncoded注解来发送表单数据。使用 @Field注解和参数来指定每个表单项的Key,value为参数的值。

@FormUrlEncoded
@POST("user/edit")
Call updateUser(@Field("first_name") String first, @Field("last_name") String last);

  当我们有很多个表单参数时可以通过@FieldMap注解和Map对象参数来指定每个表单项的Key,value的值。

@FormUrlEncoded
@POST("user/edit")
Call updateUser(@FieldMap Map fieldMap);

Multipart

  我们还可以通过@Multipart注解来发送Multipart数据。通过@Part注解来定义需要发送的文件。

@Multipart
@PUT("/user/photo")
User updateUser(@Part("photo") TypedFile photo, @Part("description") TypedString description);

Retrofit与RxJava结合

  Retrofit能够与RxJava进行完美结合。下面就来看一下Retrofit与RxJava是如何结合在一起的。对于RxJava在这就不在进行详细介绍,对于RXJava的使用可以参考附录里面给出链接。 
  首先我们需要添加如下依赖。

compile ‘com.squareup.retrofit2:adapter-rxjava:2.0.1‘
compile ‘io.reactivex:rxandroid:1.1.0‘
  • 1
  • 2
  • 1
  • 2

  创建retrofit对象实例时,通过addCallAdapterFactory来添加对RxJava的支持。

HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(httpLoggingInterceptor)
        .build();
Retrofit retrofit = new Retrofit.Builder()
        .client(okHttpClient)
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl("https://api.github.com/")
        .build();

  使用Observable创建一个API接口。

@GET("repos/{owner}/{repo}/contributors")
Observable> contributorsByRxJava(@Path("owner") String owner,@Path("repo") String repo);

  下面来调用这个API接口。

private CompositeSubscription mSubscriptiOns= new CompositeSubscription();
mSubscriptions.add(
        mGitHubService.contributorsByRxJava(mUserName, mRepo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onNext(List contributors) {
                        for (Contributor c : contributors) {
                            Log.d("TAG", "login:" + c.getLogin() + "  contributions:" + c.getContributions());
                        }
                    }
                }));

  下面来看一下运行结果。 
技术分享
  如果我们想要查看所有contributor的信息,首先我们需要向gitHub请求获取到所有contributor,然后再通过获得contributor进行依次向github请求获取contributor的信息,在这时候我们使用RxJava也就非常方便了。下面看一下如何操作的。 
  首先再添加一个API接口。

@GET("repos/{owner}/{repo}/contributors")
Observable> contributorsByRxJava(@Path("owner") String owner,
                                                   @Path("repo") String repo);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  下面在看一下是如何进行根据获得的contributor来查看contributor的信息。

mSubscriptions.add(mGitHubService.contributorsByRxJava(mUserName, mRepo)
        .flatMap(new Func1, Observable>() {
            @Override
            public Observable call(List contributors) {
                return Observable.from(contributors);
            }
        })
        .flatMap(new Func1>>() {
            @Override
            public Observable> call(Contributor contributor) {
                Observable userObservable = mGitHubService.userByRxJava(contributor.getLogin())
                        .filter(new Func1() {
                            @Override
                            public Boolean call(User user) {
                                return !isEmpty(user.getName()) && !isEmpty(user.getEmail());
                            }
                        });

                return Observable.zip(userObservable,
                        Observable.just(contributor),
                        new Func2>() {
                            @Override
                            public Pair call(User user, Contributor contributor) {
                                return new Pair<>(user, contributor);
                            }
                        });
            }
        })
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Pair pair) {
                User user = pair.first;
                Contributor cOntributor= pair.second;
                Log.d(TAG, "name:" + user.getName());
                Log.d(TAG, "contributions:" + contributor.getContributions());
                Log.d(TAG, "email:" + user.getEmail());

            }
        }))

  最后在来看下运行结果。 
技术分享

Retrofit设置缓存

对Retrofit设置缓存,由于Retrofit是对OkHttp的封装,所以我们可以直接通过OkHttpClient着手。也就是为OkHttp设置缓存。设置缓存代码如下所示。

private OkHttpClient getCacheOkHttpClient(Context context){
    final File baseDir = context.getCacheDir();
    final File cacheDir = new File(baseDir, "HttpResponseCache");
    Timber.e(cacheDir.getAbsolutePath());
    Cache cache = new Cache(cacheDir, 10 * 1024 * 1024);   //缓存可用大小为10M

    Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> {
        Request request = chain.request();
        if(!NetWorkUtils.isNetWorkAvailable(context)){
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .build();
        }

        Response originalRespOnse= chain.proceed(request);
        if (NetWorkUtils.isNetWorkAvailable(context)) {
            int maxAge = 60;                  //在线缓存一分钟
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", "public, max-age=" + maxAge)
                    .build();

        } else {
            int maxStale = 60 * 60 * 24 * 4 * 7;     //离线缓存4周
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")
                    .removeHeader("Cache-Control")
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }
    };

    return new OkHttpClient.Builder()
            .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
            .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
            .cache(cache)
            .build();
}

总结

  在retrofit的使用中,对于文件你上传与下载,并没有为我们提供进度更新的接口,在这里就需要我们自己处理了。在下面的例子中给出一个文件下载的例子,并且对下载进度更新通过logcat打印出来。可以下载进行查看。到这里retrofit的基本用法也就介绍完了,对于retrofit更多的好处在使用中我们可以慢慢体会。

源码下载

Retrifit2.0


推荐阅读
  • 在IDEA中运行CAS服务器的配置方法
    本文介绍了在IDEA中运行CAS服务器的配置方法,包括下载CAS模板Overlay Template、解压并添加项目、配置tomcat、运行CAS服务器等步骤。通过本文的指导,读者可以轻松在IDEA中进行CAS服务器的运行和配置。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了Java集合库的使用方法,包括如何方便地重复使用集合以及下溯造型的应用。通过使用集合库,可以方便地取用各种集合,并将其插入到自己的程序中。为了使集合能够重复使用,Java提供了一种通用类型,即Object类型。通过添加指向集合的对象句柄,可以实现对集合的重复使用。然而,由于集合只能容纳Object类型,当向集合中添加对象句柄时,会丢失其身份或标识信息。为了恢复其本来面貌,可以使用下溯造型。本文还介绍了Java 1.2集合库的特点和优势。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • AstridDAO 专访:波卡稳定币黑马 BAI
    加入Pol ... [详细]
  • const限定符全解一、const修饰普通变量  intconsta500;  constinta600;  上述两种情况相同,都是声明一个const型的变量,它们 ... [详细]
  • 推荐:看到如此多的MVP+Dagger2+Retrofit+Rxjava项目,轻松拿star,心动了吗?看到身边的朋友都已早早在项目中使用这些技术,而你还不会,失落吗?MVPArm ... [详细]
author-avatar
李雪萱849
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有