集合深入(List)
集合深入
List详解
ArrayList与LinkedList的区别:
1.相同点:
都是List集合中常用的实现类
对集合中的元素操作的方法基本一致
都是线程不安全的
2.不同点:
ArrayList的底层实现是数组,使用数组这种数据结构进行数据的存储
LinkedList的底层实现是双链表,使用双链表这种数据结构进行数据的存储
数组和链表结果特点比较:
数组实现功能时查找快,增删慢
链表实现功能时,查找慢,增删快
使用场景:
如果对集合中的元素,增删操作不怎么频繁,查询比较频繁时,使用ArrayList
如果对集合中的元素,增删非常频繁,查询不怎么频繁,使用LinkedList
集合对自定义对象的存储
类分为系统类和对象类
系统类往往已经重写了toString().equals(),hashcode()等方法
自定义类,为了实现我们的功能,我们往往需要重写父类的常用方法
数据结构
定义:
数据结构是计算机存储,组织数据的方式,是相互之间存在一种或多种特定关系的数据元素的集合,即带"结构"的数据元素的集合。“结构”就是指数据元素之间存在的关系,分为逻辑结构,和存储结构,通常情况下,精心选择的数据结构可以带来更高的运行和存储效率
数据的逻辑结构和物理结构是数据结构的两个密切相关的方面,同一逻辑结构可以对应着不同的存储结构,算法的设计取决于数据的逻辑结构,而算法的实现依赖于指定的存储结构
数据的逻辑结构:
指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后间关系,而与他们在计算机中的存储位置无关。逻辑结构包括:
集合:数据结构中的元素之间除了同属于一个集合的相互关系外,别无其它关系
线性结构:数据结构中的元素存在一对一的相互关系
树形结构:数据结构中的元素存在一对多的相互关系
图形结构:数据结构中的元素存在着多对多的相互关系
数据的物理结构:
指数据的逻辑结构在计算机存储空间的存放形式
常用的数据结构:
(这里的数据结构分类是从逻辑上进行的)
1.Array(数组)
数组是一种聚合数据结构,他将具有相同类型的若干变量有序地组织在一起的集合,数据可以说是最基本的数据结构,在各种编程语言中都有对应,一个数组可以分解成多个数组元素,按照数据元素的类型,数组可以分成整型数组,字符型数组,浮点型数组,指针数组,和结构数组,数组还有一维,二维以及多维等表现形式
2.stack(栈)
栈是一种特殊的线性表,他只能在一个表的一个固定的一端进行数据节点的插入和删除操作。栈是按照后进先出的原则来存储数据,也就是说,先插入的数据将被压入栈底,最后插入的数据在栈顶,读出数据时,从栈顶开始逐个读出,栈在汇编语言程序中,经常用于重要数据的现场保护,栈中没有数据时,称为空栈
3.queue(队列)
队列和栈类似,也是一种特殊的线性表,和栈不同的是,队列再进行数据的存储时,遵循先进先出的原则,而且队列只允许在表的一端进行插入操作,而在另一端进行删除操作,一般来说,进行插入操作的一端称为队尾,进行删除操作的一端称为对头,队列中,队列中没有数据元素时,成为空队列
4.LinkedList(链表)
链表是一种数据元素按照链式存储结构进行存储的数据结构,这种数据结构具有在物理上存在非连续的特点。链表有一系列数据节点构成,每个数据节点包括数据域和指针域两部分,其中,指针域保存了数据结构中下一个元素存放的地址,链表结构中的数据元素的逻辑顺序是通过链表中的指针链接次序来实现的
5.tree(树)
树是典型的非线性结构,它包括,2个结点的有穷集合K,在树结构中,有且仅有一个根结点,该结点没有前驱节点。在树结构中的其他结点都有且仅有一个前驱节点,而且可以有两个后继节点,m>=0
6.graph(图)
图是另一种非线性数据结构,在图结构中,数据节点一般称为顶点,而边是顶点的有序偶对,如果两个顶点之间存在一条边,那么就表示这两个顶点具有相邻关系
7.heap(堆)
堆是一种特殊的树形数据结构,一般讨论的堆都是二叉堆,堆的特点是根节点的值是所有结点中最小或者最大的,并且根节点的两个子树也是一个堆结构
8.hash(散列)
散列表源自散列函数(hash function)其思想是如果在数据结构中存在关键字来和T相等的记录,那么必定在F(T)的存储位置可以找到该记录,这样就不用进行比较操作而直接取得所查记录
泛型
泛型的简介:
泛型指的是“泛指的类型”。将数据类型参数化,使用泛型,将某些类型,在类与类,类与接口,方法之间进行传递,类似于传参
泛型的好处:
用在集合当中,限制存储的元素的类型,不再使用元素的时候,逐个元素进行类型检查
可以提高代码的可读性
可以使某些发生在运行时期的逻辑错误问题,提前到编译期
泛型的定义方式:
泛型是定义在<>里面的,在<>里面定义一个类型,此时,定义在<>中的类型就是泛型
泛型是一个标识符,遵循驼峰命名法
泛型一般情况下,不用太长的类型来描述,一般情况下,只需要用一个字母代替即可
如果需要定义多种泛型,直接在尖括号中定义,泛型和泛型之间以“,”分隔开来
泛型指定类型
在使用到泛型类,接口,方法的时候,指派每一个泛型具体是什么类型
注意事项:泛型类型的指派,只能是引用数据类型。泛型不能设置为基本数据类型。如果真的需要使用到基本数据类型,使用它们对应的包装类
泛型在类中的使用:
//语法
//定义:在类的后面,紧跟上<>
class Animal <T>{}
class Dog <T>{}
/*
泛型类的使用:
*/
//声明引用
Animal<String> animal;
//2.实例化对象
Animal<Integer> animal = new Animal<>();
//3.访问静态成员
Animal<Integer>.display();
//4.被继承
class Dog extends Animal<String>{}
class Dog<T> extends Animal<T>{}
泛型类的特点:
在类中定义的泛型,虽然还不明确是什么类型,但是在当前类中是可以使用的
在使用到这个类的时候,必须要指定泛型的类型,如果不指定,默认是Object
泛型,只能在当前类中使用,不能在其他的类中使用,包括子类
泛型的作用:
package bk.javase.p529;/*
学生使用工具类,用手机电话和电脑玩游戏*/
public class demo7 {public static void main(String[] args){Students student = new Students();Phone phone = new Phone("华为");Computer computer = new Computer("小米");//不用泛型加以约束,因为多态,我可以将任意子类对象作为参数传入student.setTools(computer);//tools = computer 多态student.setTools(phone); // tools = phone 多态Tools tools = student.getTools();//多态//使用泛型前if (tools instanceof Phone){Phone phone1 = (Phone)tools;phone1.callPhone();}else{throw new ClassCastException("不是Phone类");}//使用泛型后//我创建对象时,加以约束,能传的参数固定了下来,只能为CompouterStudent1<Computer> student1 = new Student1();// student1.setTools(phone);student1.setTools(computer);}
}
//使用泛型前
class Students{Tools tools;public Tools getTools() {return tools;}public void setTools(Tools tools) {this.tools = tools;}
}//使用泛型后
/*
给Student1类加泛型,方式:在类的后面直接添加<E>,E代表任意一种数据类型,这里不一定是E,任意字母都可以
这就是在类上使用泛型
在类上确定的泛型可以直接在方法上使用
当泛型,没有指定时默认是Object*/
class Student1<E>{E tools;public E getTools(){return tools;}public void setTools(E tools){this.tools = tools;}
}class Tools{String name;
}
class Phone extends Tools{public Phone(String name){this.name = name;}public void callPhone(){System.out.println("打电话");}
}
class Computer extends Tools{public Computer(String name){this.name = name;}public void play(){System.out.println("play");}
}
泛型在接口中的作用:
语法部分:
泛型接口的定义:
在接口名字的后面,添加<>,在<>里面定义泛型
interface MyInterface <T> {}
interface MyInterface<T,M>{}
泛型接口的使用:
实现类实现接口,使用接口访问接口中的静态成员,被继承
//1.实现类实现接口
class MyInterfaceImpl implements MyInterface<Person>{}
//2.使用接口访问接口中的静态成员
MyInterface<String>.test();
//3.被继承
interface SubMyinterface extends MyInterface<String>{}
泛型接口的特点:
在接口中定义的泛型,虽然还不明确是什么类型,但是在当前的接口中是可以使用的
在使用到这个接口的时候,必须要指定泛型的类型,如果不指定,默认是Object
泛型,只能在当前的接口中使用,不能在其他的接口中使用,包括子接口
package bk.javase.p529;public class demo8 {public static void main(String[] args){//使用匿名内部类的形式实现接口MyInterface<MyPerson> impl = new MyInterface<MyPerson>() {@Overridepublic int compareTo(MyPerson t1, MyPerson t2) {return 0;}};//使用lambda表达式实现接口//此时,会根据左侧的接口引用中的泛型,导出接口实际指派的类型是谁MyInterface<MyPerson> impl2 = ((t1, t2) -> t1.age - t2.age);MyInterface<String> impl3 = ((t1, t2) -> t1.length() - t2.length());}
}//定义一个泛型接口
interface MyInterface<T>{int compareTo(T t1,T t2);
}//子接口
interface SubMyInterface extends MyInterface<String>{}//实现类
class MyInterfaceImpl implements MyInterface<MyPerson>{@Overridepublic int compareTo(MyPerson t1, MyPerson t2) {return 0;}
}
class MyPerson{int age;
}
子类接口使用泛型:
第一种:子类泛型与接口泛型一致,泛型无须具体
第二种:接口使用泛型,子类不用,在实现的接口位置必须指定一个具体的数据类型
package bk.javase.p529;import java.util.ArrayList;
import java.util.Comparator;public class demo9 {public static void main(String[] args){Bird<String> bird = new Bird();bird.show("haha");}
}interface Inter<R>{public void show(R r);
}/*
子类与接口一致
类上的泛型确定了,接口上的泛型就确定了,方法上的泛型就确定了*/
class Bird<R> implements Inter<R>{@Overridepublic void show(R r) {}
}/*
接口使用泛型,子类不用
在实现接口的位置,必须指定一个具体的泛型
方法使用泛型的情况:
如果是重写的方法,泛型与接口一致
如果是子类自己的方法,可以与接口一致,也可以有自己的泛型*/
class Cat implements Inter<String>{@Overridepublic void show(String s) {}
}
class Pigs implements Comparable<Pigs>{@Overridepublic int compareTo(Pigs o) {return 0;}
}
class ComWithA implements Comparator<String>{@Overridepublic int compare(String o1, String o2) {ArrayList list = null;return 0;}
}
泛型在方法中的使用:
语法部分:
定义:泛型方法中,在定义方法时,再返回之前面通过定义泛型
public static <T> void test(){}
//在定义处的<>用来定义泛型
//在调用处的<>用来使用泛型
泛型方法的分类:
第一:方法上的泛型与类上的泛型一致
第二:方法上的独立使用泛型
在方法中定义的泛型,虽然还不明确是什么类型,但是在当前的方法是可以使用的
泛型方法,在使用的时候,不能跟类,接口似的,手动地设置类型,泛型方法中,泛型的设置,在参数中体现
泛型方法中,一定需要是有参的,参数列表中,必须有泛型类型
泛型方法中地泛型的设置,是通过在调用方法的时候,实参的类型推导出来的
泛型,只能在当前的方法中使用,不能再其他的方法中使用
第三:静态方法使用泛型
package bk.javase.p529;import java.util.ArrayList;public class demo10 {}class MyDog<E>{//第一:方法上的泛型与类上的一致public void run(E e){System.out.println(e);}//第二:方法上独立使用泛型/*注意:泛型在使用之前一定要先进行定义定义的方式:在当前方法的最前面添加<泛型>作用:让方法与方法内的泛型保持一致*/public <F> void show(F f){ArrayList<F> list = new ArrayList<>();}//静态方法使用泛型/*必须独立使用方式:在static后面定义泛型(泛型)不能使用类上定义的泛型*/public static <W> void eat(W w){}
}
关于Java中?的使用总结:
用于 ?: 中,这里是三目运算符的一部分,前面是判断条件,后面是两个分支结果
用于数据库中地sql语句,“select * from emp where name = ?”
用于泛型,是通配符,表示任意一种数据类型
//这里的Object和前面的?没有任何关系
Class<?> class = Object.class;//如果类的泛型使用时可以写成?是可以的,作为返回值时,会默认成Object类型,但是作为参数不行,所以在给对象指定泛型的时候要写具体的类型
Test<?> test = new Test();//test.run(new Object());错误
class Test<T>{T t;public T run(T a){T t = null;return t;}
}
限制上限<? extends E>:
定义:限制的是整个<>可以取的泛型类型的上限是E,<>中可以取得是E以及E的子类
限制下限<? super E>:
定义:限制的是整个的<>可以取得泛型类型的下限是E,<>中可以取得类型是E以及E的父类
Collection工具类:
API:
返回值 | 方法 | 描述 |
---|---|---|
static boolean | addAll() | 批量向一个集合中添加数据 |
static | max() | 获取集合中最大的元素 |
static T | min() | 获取集合中最小的元素 |
static | shuffle() | 将集合中的元素随机排列 |
static void | swap() | 交换集合中的两个元素 |
static void | reverse() | 将集合中的元素倒序 |
static void | sort () | 将集合中的元素升序排序 |
static int | binarySearch() | 使用二分查找法查询元素下标 |
static void | copy() | 拷贝 |
static void | fill() | 使用指定的值填充集合 |
static Collection<T | synchronizedCollection | 获取一个线程安全的集合 |
package bk.javase.p529;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class demo12 {public static void main(String[] args){//1.实例化一个List集合对象List<Integer> list = new ArrayList<>();//2.添加元素Collections.addAll(list,10,20,30,40);//3.获取一个集合中的最大值,大小比较通过比较元素对应的类实现的Comparable接口进行比较Integer max = Collections.max(list);//获取一个集合中的最大值,大小比较通过第二个参数ComparatorInteger max2 = Collections.max(list,(i1,i2) ->i2-i1);//4.获取一个集合中的最小值,大小比较通过元素对应的实现类实现的Comparable接口进行比较Integer min = Collections.min(list);//获取一个集合中的最小值,大小比较通过第二个参数ComparatorInteger min2 = Collections.min(list,(i1,i2)->i2-i1);//5.将List集合中的数据进行随机的排列(洗牌)Collections.shuffle(list);//6.交换一个List集合中两个下标对应的元素Collections.swap(list,0,2);//7.将一个List集合中的元素进行倒序排列Collections.reverse(list);//8.将一个List集合进行排序,元素的大小比较规则是使用元素对应的实现类实现Comparable接口进行比较大小Collections.sort(list);//将一个List集合中的元素按照制定的规则进行升序排序(基本不用),List集合中本身就有这样的排序方法Collections.sort(list,(i1,i2)->i2-i1);//9.元素的拷贝,将第二个参数集合中的数据拷贝到第一个集合中List<Integer> copy = new ArrayList<>();Collections.addAll(copy,0,0,0,0,0);Collections.copy(copy,list);//10.使用指定的数据填充一个集合Collections.fill(list,0);//11.将线程不安全的集合转成线程安全的集合
// Collections.synchronizedCollection();
// Collections.synchronizedList();
// Collections.synchronizedSet();
// Collections.synchronizedMap();}
}
集合深入(List)相关推荐
- do还是doing imagine加to_中学必背英语短语集合:54个doing动名词的固定搭配
中学必背英语短语集合:54个doing动名词的固定搭配mp.weixin.qq.com doing动名词是中小学英语教学中的重要内容.在小学的时候老师大概会把doing解释为一般进行时,但层级越往上 ...
- Redis 笔记(07)— sorted set 类型(添加、删除有序集合元素、获取分数范围内成员、按score排序、返回集合元素个数)
zset 可能是 Redis 提供的最为特色的数据结构,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权 ...
- Redis 笔记(06)— set 类型(向集合添加元素、获取集合元素个数、判断集合中是否包含某个元素、删除给定元素、返回集合中所有元素、计算集合的交集、并集、差集)
Redis 的 set 集合内部的键值对是无序的唯一的.它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL .当集合中最后一个元素移除之后,数据结构自动删除,内存被回收. ...
- 【C#】集合_哈希表_字典_泛型_文件
数组能做到:存放同种类型数据,且数据个数确定 object类型的数组能满足:放各种类型的数据,确定放多少个,但是随意插入元素,数组做不到 集合能做到:存放各种数据类型,且不确定存放多少个,能做到随意插 ...
- java集合中对象某属性比较排序
TreeSet:它可以给Set集合中的元素进行指定方式的排序. 保证元素唯一性的方式:通过比较的结果是否为0. 底层数据结构是:二叉树. 排序的第一种方式: 让元素自身具备比较性.只要让元素实现Com ...
- 程序员应该吃透的集合List
一:先看看集合框架接口图 (图片来源于网络) 从图中可以看到List实现了Collection接口. 二:Collection接口是什么? 在java类库中,Collection接口是集合类的基本接口 ...
- Java集合详解之Map
一.首先看看集合框架体系图 从图中可以看到,Map接口扩展了Iterator接口,关于Iterator接口详解请移步:Iterator接口详解 二.Map是什么? Map<k,v>使用键值 ...
- 第一个python程序:定义,列表,元组,集合,求并集交集,键和值,运算符,缩进
''' 来源:天善智能韦玮老师课堂笔记 ''' print("定义") a = 6 # python里无需定义 print("a=",a) a += 1 # + ...
- python 获取集合里面的某一个元素
python 获取集合里面的某一个元素,想想呢集合是不支持所以,切片,相加,相乘操作的, 所以想获取集合里面的某一个元素需要转化下思路,比如把即可转成列表然后在利用索引获取 例如: list_a = ...
- python 把列表或者元组转成集合
python 把列表或者元组转成集合 使用set 方法 list_a = ["张三", "李四", "王二"] # 把列表转成集合 prin ...
最新文章
- Earth to developers: Grow up!
- 「SAP技术」交货单发货过账报错 - Material's product unit must be entered in whole numbers - 之对策
- hashmap中用红黑树不用其他树_HashMap面试专题:常问六题深入解析
- ZeroMQ接口函数之 :zmq_pgm – ØMQ 使用PGM 进行可靠的多路传输
- HDFS数据的写入过程
- String类中不同拼接方式
- 深度残差收缩网络再次理解(论文地址+代码地址+代码理解)
- 素数的有关性质(二)欧拉函数的一些定理证明与计算
- Java native方法String转char*以及String[]转char**
- 后代选择+++margin-right:auto
- python怎么筛选excel数据_Python操作三个excel并过滤数据,python,筛选,其中
- JavaWeb——响应编码与请求编码
- 产品思维训练 | 经典产品面试题
- arcgis语言如何中文改英文_值得收藏|不重装软件实现ArcGIS中英文版本之间切换...
- 一文读懂社交网络分析(附应用、前沿、学习资源)
- CGB2202-DAY02-IO低级流与高级流
- excel中if如何加android,Excel 如何实现函数IF的嵌套超过七层
- C++实现windows平台下音频播放音量调节功能
- 电脑计算机显示向程序发送命令时出现问题,word提示向程序发送命令时出现问题怎么解决 wo...
- HTML 图片热点map area使用方法
热门文章
- 在python中、实例变量在类的内部通过_【python】类变量、实例变量
- 消息队列的优势与缺点
- Python程序员面试中,被常问的七道题!(详细解题思路)
- Day16 ajax-上
- 用Nvidia的PerfHud剖析《寻仙》
- 怎么安装安卓模拟器BlueStacks
- Djava.endorsed.dirs=D:\Tomcat 9.0\endorsed is not supported
- TZC 1283: 简单排序 —— 插入排序
- SHA1和SHA256算法C语言实现
- java毕业设计派大星水产商城mp4(附源码、数据库)