• HttpClient别说话,用心看


    文档D:\httpclient-demo

    官网:Apache HttpComponents – Apache HttpComponents

    常见使用场景:1.爬虫(python相对做爬虫专业,但是java也可以做)  2.与其他应用进行交互时候

    注意下,不同的HttpClient的jar包版本,API和包路径有明显不同

    先使用JDK原生API请求网页

     将控制台的复制保存为html文件

     双击打开

     request:请求行,请求头,请求体

    可以设置请求方式,请求头,等

     依赖

    1. <dependency>
    2. <groupId>org.apache.httpcomponents</groupId>
    3. <artifactId>httpclient</artifactId>
    4. <version>4.5.13</version>
    5. </dependency>

    演示使用HttpClient发送get请求,无参

    1. @Test
    2. public void test1(){
    3. //可关闭的httpclient客户端,相当于打开一个浏览器
    4. CloseableHttpClient closeableHttpClient=HttpClients.createDefault();
    5. String str="https://www.baidu.com";
    6. //构造HttpGet请求对象
    7. HttpGet httpGet=new HttpGet(str);
    8. //声明可关闭响应对象
    9. CloseableHttpResponse response = null;
    10. try {
    11. //可关闭的httpclient客户端对象执行httpGet请求
    12. response=closeableHttpClient.execute(httpGet);
    13. //获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体
    14. //作为响应结果的实现类是DecompressingEntity
    15. HttpEntity httpEntity=response.getEntity();
    16. //对HttpEntity操作的工具类
    17. String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
    18. System.out.println(toStringResult);
    19. //确保流关闭
    20. EntityUtils.consume(httpEntity);
    21. } catch (Exception e) {
    22. e.printStackTrace();
    23. }finally {
    24. if(response!=null){
    25. try {
    26. response.close();
    27. } catch (IOException e) {
    28. e.printStackTrace();
    29. }
    30. if(closeableHttpClient!=null){
    31. try {
    32. closeableHttpClient.close();
    33. } catch (IOException e) {
    34. e.printStackTrace();
    35. }
    36. }
    37. }
    38. }
    39. }

    控制台打印结果和原先一样

    关于user-agent和referer:

    user-agent意思是用户代理:客户端用的什么浏览器

    假如一直用Httpclient连接某些网页,如果对方知道你是机器所为

    比如下面这样

     可以在请求头里设置user-agent

    比如在请求对象里设置:

    //构造HttpGet请求对象
    HttpGet httpGet=new HttpGet(str);
    httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");

    这样一般可以解决httpClient被认为不是真人行为

    另外网站为了保护自己,比如爬对方图片,进行防盗链设置

    而Referer是用来,解决网站防盗链

    每个请求头,都有对应的作用,自己可查看资料

    下面演示,一个网站通过浏览器访问后端,后端获取所有请求头,和通过HttpClien发送请求,所得到的请求头有哪些不一样。

    该demo一会上传百度云盘

    前端就几个表单,做为参数通过get,post,还有文件上传的演示

    后端接收,并打印所有由浏览器发起请求的所有请求头

    随便用户名,密码,这里输入aaa,密码 bbb 后端得到的所有请求头

    且账号密码  都是Okde

     然后再实验 账户aaa,密码aaa+bbb

     

    再来看看用HttpClien发送该请求,后端的结果 

    也用 aaa  bbb

    HttpClient代码  主要注意一点,就是表单提交时候 比如用户名是aaa+bbb的时候,会自动帮我们编码

    而如果用HttpClient直接将用户名aaa+bbb  密码xxx这样进行提交的话,后台收到的+号会变空格,甚至说比如空格等特殊符号,直接给你报错了,就是说不让你用HttpClient提交该请求

    比如String str=http://localhost:8899/httpclient-demo/test1?userName=aaa  空格  Bbbb&password=bbb

    就直接给你报错

    1. /**
    2. * 使用httpclient发送get请求
    3. */
    4. @Test
    5. public void test1(){
    6. //可关闭的httpclient客户端,相当于打开一个浏览器
    7. CloseableHttpClient closeableHttpClient=HttpClients.createDefault();
    8. //String str="http://localhost:8899/httpclient-demo/test1?userName=aaa%2Bbbb&password=bbb";
    9. String str="http://localhost:8899/httpclient-demo/test1?userName="+"aaa+bbb"+"&password=bbb";
    10. //构造HttpGet请求对象
    11. HttpGet httpGet=new HttpGet(str);
    12. httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
    13. //httpGet.addHeader("Referer","http://localhost:8899/httpclient-demo/test1?userName=aaa%2Bbbb&password=bbb");
    14. //声明可关闭响应对象
    15. CloseableHttpResponse response = null;
    16. try {
    17. //可关闭的httpclient客户端对象执行httpGet请求
    18. response=closeableHttpClient.execute(httpGet);
    19. //获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体
    20. //作为响应结果的实现类是DecompressingEntity
    21. HttpEntity httpEntity=response.getEntity();
    22. //对HttpEntity操作的工具类
    23. String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
    24. System.out.println(toStringResult);
    25. //确保流关闭
    26. EntityUtils.consume(httpEntity);
    27. } catch (Exception e) {
    28. e.printStackTrace();
    29. }finally {
    30. if(response!=null){
    31. try {
    32. response.close();
    33. } catch (IOException e) {
    34. e.printStackTrace();
    35. }
    36. if(closeableHttpClient!=null){
    37. try {
    38. closeableHttpClient.close();
    39. } catch (IOException e) {
    40. e.printStackTrace();
    41. }
    42. }
    43. }
    44. }
    45. }

    报错的演示

    想说明的一点是,用浏览器提交表单请求时候,浏览器会帮我们自动对中文和特殊符号进行编码,后端会自行解码,但是当使用HttpClient的时候用注意中文和特殊符号

    那么就要将到URLEncode  它可以对RUL上的特殊字符进行编码

    用浏览器,提交时候会自动完成URLEncode 而当使用HttpClient时候,中文与特殊符号就需要我们自己使用URLEncode进行编码

    丫的CSDN不能上传图片了

    就是用URLEncode对get请求进行编码即可

    String str="http://localhost:8899/httpclient-demo/test1?userName=   "+"aaa+bbb"+"&password=bbb";
    try {
        str=URLEncoder.encode(str, StandardCharsets.UTF_8.name());
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    这里注意一点,上面这么做是错的

    由于一时没法发图片,这么做的话,会将整个url全部编码,也就是说://  &  ?等等全部进行了编码

    而我们只需要对我们上传的参数进行编码,因此正确做法是

    lic void test1(){
        //可关闭的httpclient客户端,相当于打开一个浏览器
        CloseableHttpClient closeableHttpClient=HttpClients.createDefault();
        //String str="http://localhost:8899/httpclient-demo/test1?userName=aaa%2Bbbb&password=bbb";
        String userName="aaa 哈哈";
        String password="你妹";
        try {
            //对自定义上传的进行编码
            userName=URLEncoder.encode(userName, StandardCharsets.UTF_8.name());
            password=URLEncoder.encode(password, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            e.printStackTrace();
        }
        String str="http://localhost:8899/httpclient-demo/test1?+userName="+userName+"&password="+password;

    对HttpClient做了些改动,没法发图说明,全复制了一遍

    1. /**
    2. * 使用httpclient发送get请求
    3. */
    4. @Test
    5. public void test1(){
    6. //可关闭的httpclient客户端,相当于打开一个浏览器
    7. CloseableHttpClient closeableHttpClient=HttpClients.createDefault();
    8. String userName="收到 你没";
    9. String password="阿斯顿)(";
    10. try {
    11. userName= URLEncoder.encode(userName, StandardCharsets.UTF_8.name());
    12. password=URLEncoder.encode(password, StandardCharsets.UTF_8.name());
    13. } catch (Exception e) {
    14. e.printStackTrace();
    15. }
    16. String str="http://localhost:8899/httpclient-demo/test1?userName="+userName+"&password="+password;
    17. //构造HttpGet请求对象
    18. HttpGet httpGet=new HttpGet(str);
    19. httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
    20. //httpGet.addHeader("Referer","https://www.amamaw.com");
    21. //声明可关闭响应对象
    22. CloseableHttpResponse response = null;
    23. try {
    24. //可关闭的httpclient客户端对象执行httpGet请求
    25. response=closeableHttpClient.execute(httpGet);
    26. //代表本次请求成功或者失败的状态
    27. StatusLine statusLine=response.getStatusLine();
    28. if(HttpStatus.SC_OK==statusLine.getStatusCode()){//HttpStatus里有所有状态码 200 404 302等等
    29. System.out.println("响应成功");
    30. //获取所有响应头
    31. Header[] allHeader=response.getAllHeaders();
    32. for(Header header:allHeader){
    33. System.out.println("响应头:"+header.getName()+":"+header.getValue());
    34. }
    35. //成功了再获取响应结果
    36. //获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体
    37. //作为响应结果的实现类是DecompressingEntity
    38. HttpEntity httpEntity=response.getEntity();
    39. System.out.println("ContentType:"+httpEntity.getContentType());
    40. //对HttpEntity操作的工具类
    41. String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
    42. System.out.println(toStringResult);
    43. //确保流关闭
    44. EntityUtils.consume(httpEntity);
    45. }else{
    46. System.out.println("响应失败,响应码是:"+statusLine.getStatusCode());
    47. }
    48. } catch (Exception e) {
    49. e.printStackTrace();
    50. }finally {
    51. if(response!=null){
    52. try {
    53. response.close();
    54. } catch (IOException e) {
    55. e.printStackTrace();
    56. }
    57. if(closeableHttpClient!=null){
    58. try {
    59. closeableHttpClient.close();
    60. } catch (IOException e) {
    61. e.printStackTrace();
    62. }
    63. }
    64. }
    65. }
    66. }

    关于保存网络图片到本地:粗暴点讲就是爬取图片,再写个demo

    1. @Test
    2. public void test3(){
    3. //可关闭的httpclient客户端,相当于打开一个浏览器
    4. CloseableHttpClient closeableHttpClient=HttpClients.createDefault();
    5. String userName="收到 你没";
    6. String password="阿斯顿)(";
    7. try {
    8. userName= URLEncoder.encode(userName, StandardCharsets.UTF_8.name());
    9. password=URLEncoder.encode(password, StandardCharsets.UTF_8.name());
    10. } catch (Exception e) {
    11. e.printStackTrace();
    12. }
    13. String str="https://img-blog.csdnimg.cn/c2c20ed7275749bba0e43cdf9d66a9d7.png";
    14. //String str="http://localhost:8899/httpclient-demo/test1?userName="+userName+"&password="+password;
    15. //构造HttpGet请求对象
    16. HttpGet httpGet=new HttpGet(str);
    17. httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
    18. //httpGet.addHeader("Referer","https://www.amamaw.com");
    19. //声明可关闭响应对象
    20. CloseableHttpResponse response = null;
    21. try {
    22. //可关闭的httpclient客户端对象执行httpGet请求
    23. response=closeableHttpClient.execute(httpGet);
    24. //代表本次请求成功或者失败的状态
    25. StatusLine statusLine=response.getStatusLine();
    26. if(HttpStatus.SC_OK==statusLine.getStatusCode()){//HttpStatus里有所有状态码 200 404 302等等
    27. System.out.println("响应成功");
    28. //获取所有响应头
    29. Header[] allHeader=response.getAllHeaders();
    30. for(Header header:allHeader){
    31. System.out.println("响应头:"+header.getName()+":"+header.getValue());
    32. }
    33. //成功了再获取响应结果
    34. //获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体
    35. //作为响应结果的实现类是DecompressingEntity
    36. HttpEntity httpEntity=response.getEntity();
    37. //获取图片,一般图片都有后缀,如何保存为原有的后缀 image/jpg image/png image/jpeg image/图片后缀
    38. String contenType= httpEntity.getContentType().getValue();
    39. String suffix=".jpg";
    40. if(contenType.contains("jpg")||contenType.contains("jpeg")){
    41. suffix=".jpg";
    42. }else if(contenType.contains("bmp")||contenType.contains("bitmap")){
    43. suffix=".bmp";
    44. }else if(contenType.contains("png")){
    45. suffix=".png";
    46. }else if(contenType.contains("gif")){
    47. suffix=".gif";
    48. }
    49. //图片是二进制,toByteArray()可以以流的形式获取任何 文本也可以 图片 视频都行
    50. byte[] bytes=EntityUtils.toByteArray(httpEntity);
    51. // String str1=new String(bytes);
    52. // System.out.println("str1="+str1);
    53. //定义个本地保存图片的路径
    54. String localAbsPath="D:\\pachongimage\\"+new SimpleDateFormat("yyyyHHmmhhmmss").format(new Date())+suffix;
    55. //写入文件
    56. FileOutputStream fos=new FileOutputStream(localAbsPath);
    57. fos.write(bytes);
    58. fos.close();
    59. System.out.println("ContentType:"+httpEntity.getContentType());
    60. //对HttpEntity操作的工具类 注意图片是二进制文件,不能再toString()了 只有文本可以
    61. //String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
    62. //System.out.println(toStringResult);
    63. //确保流关闭
    64. EntityUtils.consume(httpEntity);
    65. }else{
    66. System.out.println("响应失败,响应码是:"+statusLine.getStatusCode());
    67. }
    68. } catch (Exception e) {
    69. e.printStackTrace();
    70. }finally {
    71. if(response!=null){
    72. try {
    73. response.close();
    74. } catch (IOException e) {
    75. e.printStackTrace();
    76. }
    77. if(closeableHttpClient!=null){
    78. try {
    79. closeableHttpClient.close();
    80. } catch (IOException e) {
    81. e.printStackTrace();
    82. }
    83. }
    84. }
    85. }
    86. }

    这样该目录里就有该图片了

    设置访问代理,设置访问代理原因,爬虫写多了,高频率访问网站,对方安全性做的比较好的话,会将你IP封掉.那么做爬虫的应对方式就是设置访问代理,用不同IP去访问,请求,避免被封,让它搞不清楚

    设置访问代理,有免费的,但是不太稳定,要稳定加钱......

    另外再写个Demo

    无论HttpGet或者HttpPost都可以配置  这里用HttpGet演示   代理的IP和端口网上找的

    //创建一个代理
    String ip="120.26.123.95";
    int port=8010;
    //构造HttpGet请求对象
    HttpGet httpGet=new HttpGet(str);
    HttpHost proxy=new HttpHost(ip,port);
    //对每一个请求进行配置,会覆盖全局的默认请求配置
    RequestConfig requestConfig= RequestConfig.custom().setProxy(proxy).build();
    httpGet.setConfig(requestConfig);
    1. /**
    2. * 演示设置访问代理
    3. */
    4. @Test
    5. public void test4(){
    6. //可关闭的httpclient客户端,相当于打开一个浏览器
    7. CloseableHttpClient closeableHttpClient=HttpClients.createDefault();
    8. String str="http://www.baidu.com";
    9. //创建一个代理
    10. String ip="120.26.123.95";
    11. int port=8010;
    12. //构造HttpGet请求对象
    13. HttpGet httpGet=new HttpGet(str);
    14. HttpHost proxy=new HttpHost(ip,port);
    15. //对每一个请求进行配置,会覆盖全局的默认请求配置
    16. RequestConfig requestConfig= RequestConfig.custom().setProxy(proxy).build();
    17. httpGet.setConfig(requestConfig);
    18. //声明可关闭响应对象
    19. CloseableHttpResponse response = null;
    20. try {
    21. //可关闭的httpclient客户端对象执行httpGet请求
    22. response=closeableHttpClient.execute(httpGet);
    23. //代表本次请求成功或者失败的状态
    24. StatusLine statusLine=response.getStatusLine();
    25. if(HttpStatus.SC_OK==statusLine.getStatusCode()){//HttpStatus里有所有状态码 200 404 302等等
    26. System.out.println("响应成功");
    27. //获取所有响应头
    28. Header[] allHeader=response.getAllHeaders();
    29. for(Header header:allHeader){
    30. System.out.println("响应头:"+header.getName()+":"+header.getValue());
    31. }
    32. //成功了再获取响应结果
    33. //获取响应结果 注意HttpEntity有很多实现类,不仅仅可以作为响应结果,还可以作为请求的参数实体
    34. //作为响应结果的实现类是DecompressingEntity
    35. HttpEntity httpEntity=response.getEntity();
    36. System.out.println("ContentType:"+httpEntity.getContentType());
    37. //对HttpEntity操作的工具类 注意图片是二进制文件,不能再toString()了 只有文本可以
    38. String toStringResult=EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
    39. System.out.println(toStringResult);
    40. //确保流关闭
    41. EntityUtils.consume(httpEntity);
    42. }else{
    43. System.out.println("响应失败,响应码是:"+statusLine.getStatusCode());
    44. }
    45. } catch (Exception e) {
    46. e.printStackTrace();
    47. }finally {
    48. if(response!=null){
    49. try {
    50. response.close();
    51. } catch (IOException e) {
    52. e.printStackTrace();
    53. }
    54. if(closeableHttpClient!=null){
    55. try {
    56. closeableHttpClient.close();
    57. } catch (IOException e) {
    58. e.printStackTrace();
    59. }
    60. }
    61. }
    62. }

    关于连接超时,和读取超时的设置与具体含义

    关于连接超时,也是通过RequestConfig来进行设置的,这里先把代理去掉

    就是设置HTTP三次握手的时间上限,连接超时就报ConnectTimeoutException

    //对每一个请求进行配置,会覆盖全局的默认请求配置
    RequestConfig requestConfig= RequestConfig.custom().setConnectTimeout(5000).build();
    //对每一个请求进行配置,会覆盖全局的默认请求配置
    RequestConfig requestConfig= RequestConfig.custom()
            //设置CTP三次握手的时间上线
            .setConnectTimeout(55555)
            //设置从请求的网址获取响应数据的时间渐渐
            .setSocketTimeout(50000)
            //指从连接池获取connection的超时时间
            .setConnectionRequestTimeout(5000)
            .build();
    httpGet.setConfig(requestConfig);

    接着演示,用HttpClient发送  

    Content-Type分别为:

    1.application/x-www-form-urlencoded

    2.application/json

    3multipart/form-data(文件上传时的Content-Type类型)

    的Post请求

    1.用HttpClient发送content-type为application/x-www-form-urlencoded的post请求

    demo送上    注意:content-type为application/x-www-form-urlencoded

    他的参数格式是在body体中:KEY1=VALUE1&KEY2=VALUE2的格式

    其实下面传送过去的也就是userName=java&password=xxxx的格式

    NameValuePair是个接口,BasicNameValuePair是他的一个实现类
    1. /**
    2. * - 发送application/x-www-form-urlencoded类型的post请求
    3. *
    4. * @throws Exception
    5. */
    6. @Test
    7. public void testPost1() throws Exception {
    8. CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
    9. String urlStr = "http://localhost:8899/httpclient-demo/test2";
    10. // 创建httppost对象
    11. HttpPost httpPost = new HttpPost(urlStr);
    12. // 设置请求头
    13. httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
    14. // 给post对象设置参数
    15. /*
    16. NameValuePair: <input id="user-name-label" type="text" name="userName"/>
    17. 的name(userName)和input标签里面输入的值就构成了一个NameValuePair对象
    18. */
    19. List<NameValuePair> list = new ArrayList<>();
    20. list.add(new BasicNameValuePair("userName", "java"));
    21. list.add(new BasicNameValuePair("password", "xxxxx"));
    22. // 把参数集合设置到formEntity
    23. UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);
    24. httpPost.setEntity(formEntity);
    25. CloseableHttpResponse response = null;
    26. try {
    27. response = closeableHttpClient.execute(httpPost);
    28. HttpEntity entity = response.getEntity();
    29. String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
    30. System.out.println(toStringResult);
    31. EntityUtils.consume(entity);
    32. } catch (Exception e) {
    33. e.printStackTrace();
    34. } finally {
    35. if (closeableHttpClient != null) {
    36. try {
    37. closeableHttpClient.close();
    38. } catch (IOException e) {
    39. e.printStackTrace();
    40. }
    41. }
    42. if (response != null) {
    43. try {
    44. response.close();
    45. } catch (IOException e) {
    46. e.printStackTrace();
    47. }
    48. }
    49. }
    50. }

    2.用HttpClient发送content-type为application/json的post请求

    在body体中的格式就是JSON

    {

            "userName":"java",
            "password":"xxxx",

             "age":18

    }

    Demo送上

    1. /**
    2. * - 发送application/json类型的post请求
    3. */
    4. @Test
    5. public void testPost2() throws Exception {
    6. CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
    7. String urlStr = "http://localhost:8899/httpclient-demo/testJson";
    8. // 创建httppost对象
    9. HttpPost httpPost = new HttpPost(urlStr);
    10. // string:是一个json字符串
    11. JSONObject jsonObj = new JSONObject();
    12. jsonObj.put("userName", "java");
    13. jsonObj.put("password", "不知道写什么");
    14. StringEntity jsonEntity = new StringEntity(jsonObj.toString(), Consts.UTF_8);
    15. // 也需要给entity设置一下内容类型
    16. // jsonEntity.setContentType(new BasicHeader("Content-Type","application/json; charset=utf-8"));
    17. jsonEntity.setContentType("application/json; charset=utf-8");
    18. // 设置entity的编码
    19. jsonEntity.setContentEncoding(Consts.UTF_8.name());
    20. httpPost.setEntity(jsonEntity);
    21. CloseableHttpResponse response = null;
    22. try {
    23. response = closeableHttpClient.execute(httpPost);
    24. HttpEntity entity = response.getEntity();
    25. String toStringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
    26. System.out.println(toStringResult);
    27. EntityUtils.consume(entity);
    28. } catch (Exception e) {
    29. e.printStackTrace();
    30. } finally {
    31. if (closeableHttpClient != null) {
    32. try {
    33. closeableHttpClient.close();
    34. } catch (IOException e) {
    35. e.printStackTrace();
    36. }
    37. }
    38. if (response != null) {
    39. try {
    40. response.close();
    41. } catch (IOException e) {
    42. e.printStackTrace();
    43. }
    44. }
    45. }
    46. }

  • 相关阅读:
    用 Rust 和 cURL 库制作一个有趣的爬虫
    java基于springboot+vue协同过滤算法的音乐推荐系统
    洋酒销售系统的设计与实现(附源码+资料+论文+截图+数据库)
    React中的useCallback和useMemo
    SSM学习——springboot整合ssm(15)
    解决GDAL 写FileGDB的中文属性字段和字段值乱码。
    买下房子却发现被查封了,怎么办?
    非线性有限元:基本理论与算法及基于Python、Fortran程序实现与案例分析
    【基础讲解】基于matpower的电力系统潮流计算(Matlab代码实现)
    【Java】【集合】集合框架Collection
  • 原文地址:https://blog.csdn.net/tiantiantbtb/article/details/128027106