jjzjj

对集合、复杂度以及泛型的认识

crazy_xieyi 2024-05-24 原文

文章目录


 


一、集合框架是什么?

Java 集合框架 Java Collection Framework ,又被称为容器 container ,是定义在 java.util 包下的一组接口 interfaces 和其实现类 classes 。
类和接口如下:

 

 1. Collection:是一个接口,包含了大部分容器常用的一些方法
2. List:是一个接口,规范了ArrayList 和 LinkedList中要实现的方法
            ArrayList:实现了List接口,底层为动态类型顺序表
            LinkedList:实现了List接口,底层为双向链表
3. Stack:底层是栈,栈是一种特殊的顺序表
4. Queue:底层是队列,队列是一种特殊的顺序表
5. Deque:是一个接口
6. Set:集合,是一个接口,里面放置的是K模型
           HashSet:底层为哈希桶,查询的时间复杂度为O(1)
           TreeSet:底层为红黑树,查询的时间复杂度为O(log以2为底N ),关于key有序的
7. Map:映射,里面存储的是K-V模型的键值对
           HashMap:底层为哈希桶,查询时间复杂度为O(1)
           TreeMap:底层为红黑树,查询的时间复杂度为O(log以2为底N  ),关于key有序

二、复杂度

1.时间复杂度

2.空间复杂度

这里请参考之前写的一篇关于复杂度的博客:如何评价一个算法的好坏?-复杂度_crazy_xieyi的博客-CSDN博客大O表示法来描述复杂度,需要忽略常数、系数和低阶。O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)。用尽量小的存储空间,用尽量少的执行步骤。第64个斐波那契数(n=64),用O(n)计算大约耗时6.4*10^(-8)秒,用O(2^n)计算大约耗时584.94年。...https://blog.csdn.net/crazy_xieyi/article/details/126062123?spm=1001.2014.3001.5501

这里看一个非常经典的题目:

// 计算斐波那契递归的复杂度?
int fifibonacci(int N) {
return N < 2 ? N : fifibonacci(N-1)+fifibonacci(N-2);
}

1.时间复杂度

这里就要分析递归了多少次。

 计算执行次数,为等比数列求和:2^0+2^1+2^2+......+2^(n-1)=2^n-1

所以时间复杂度为:O(2^N)

 2.空间复杂度

在计算空间复杂度的时候,需要注意一点就是:当一条链路递归完成之后,返回来的时候,其所占的空间就被释放了,所以空间复杂度以最长链路为准,及空间复杂度为:O(N)

三、泛型

泛型是在JDK1.5引入的新的语法,通俗讲,泛型 就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。在编译的时候会进行类型的检查和转换。
 
小技巧:设置泛型:shift + F6
 
语法
泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象

 

注意:泛型只能接受类,所有的基本数据类型必须使用包装类!

 

当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写。

MyArray<Integer> list = new MyArray<>(); 

擦除机制

在编译的时候会进行类型检查,最后在编译完成的字节码文件中,都变成了Object。

泛型的上界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

 

public class MyArray<E extends Number> {
...
}

 

只接受 Number 的子类型作为 E 的类型实参。此时E是 Number的子类或Number本身,因为此时引入了泛型的上界,那么在擦除之后,为Number。

注意: 没有指定类型边界 E,可以视为 E extends Object 

如果涉及到元素的比较,那么E必须是实现了Comparable接口的。

 

public class MyArray<E extends Comparable<E>> {
...
}

 通配符

? 用于在泛型的使用,即为通配符。
 
一个例子:
public class TestDemo {
   public static void main(String[] args) {
      Message<Integer> message = new Message() ;
      message.setMessage(55);
      fun(message);
   }
   // 此时使用通配符"?"描述的是它可以接收任意类型,但是由于不确定类型,所以无法修改
   public static void fun(Message<?> temp){
      //temp.setMessage(100); 无法修改!
      System.out.println(temp.getMessage());
   }
}

1.通配符上界

? extends 类:设置泛型上界

 

<? extends 上界>
例子:<? extends Number>//可以传入的实参类型是Number或者Number的子类

 通配符的上界,不能进行写入数据(不确定具体类型),只能进行读取数据(因为一定可以用Number接收)

2.通配符下界

 

<? super 下界>
例子:<? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型

相反,通配符的下界,不能进行读取数据(因为无法知道取出的数据类型具体是什么),只能写入数据(此时可以放入Integer的父类)

 

 

有关对集合、复杂度以及泛型的认识的更多相关文章

  1. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  2. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  3. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  4. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  5. ruby - 使用 AES 的 Rails 加密,过于复杂 - 2

    我在加密来self正在使用的第三方供应商的值时遇到问题。他们的指令如下:1)Converttheencryptionpasswordtoabytearray.2)Convertthevaluetobeencryptedtoabytearray.3)Theentirelengthofthearrayisinsertedasthefirstfourbytesontothefrontofthefirstblockoftheresultantbytearraybeforeencryption.4)EncryptthevalueusingAESwith:1.256-bitkeysize,2.25

  6. ruby - 测试一个复杂的方法 - 2

    我正在开发西洋跳棋实现,其中有许多易于测试的方法,但我不确定如何测试我的主要#play_game方法。我的大多数方法都可以很容易地确定输入和输出,因此也很容易测试,但这种方法是多方面的,实际上并没有容易辨别的输出。这是代码:defplay_gameputs@gui.introwhile(game_over?==false)message=nil@gui.render_board(@board)@gui.move_requestplayer_input=getscoordinates=UserInput.translate_move_request_to_coordinates(play

  7. ruby - 是否有用于复杂比较的漂亮语法? - 2

    方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(

  8. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  9. ruby-on-rails - 如何构建复杂的 Rails 系统 - 2

    关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和

  10. ruby - ruby 中的同一个程序如何接受来自用户的输入以及命令行参数 - 2

    我的ruby​​脚本从命令行参数获取某些输入。它检查是否缺少任何命令行参数,然后提示用户输入。但是我无法使用gets从用户那里获得输入。示例代码:test.rbname=""ARGV.eachdo|a|ifa.include?('-n')name=aputs"Argument:#{a}"endendifname==""puts"entername:"name=getsputsnameend运行脚本:rubytest.rbraghav-k错误结果:test.rb:6:in`gets':Nosuchfileordirectory-raghav-k(Errno::ENOENT)fromtes

随机推荐