当前位置:网站首页>集合(泛型 & List & Set & 自定义排序)
集合(泛型 & List & Set & 自定义排序)
2022-07-06 16:53:00 【一个很懒的人】
本文主要介绍了集合的指示,包括但不限于以下知识:
- 泛型
- 集合体系层级
- 集合体系中的接口及其实现类
- 集合自定义排序
集合
1.泛型
(1)概念
将 数据类型 作为 参数 进行传递
(泛型在使用时,接收到的是什么数据类型,此泛型就是什么数据类型)
(2)定义
1,<T>:T 声明一个泛型,可以使用任何字母,代指泛型,eg:<T>、<X>
2,<T,X,...>:声明多个泛型,T、X.....
(3)使用
注意:
- 泛型必须:先定义,再使用
- 泛型在使用时,接收到的是什么数据类型,此泛型就是什么数据类型
- 泛型可以在数据类型处定义
- 泛型在类中定义的只能在类中使用,在方法中定义的只能在方法中使用(泛型作用域范围)
- 使用泛型的类,在 创建对象 时要指明 实际 的数据类型(只能用引用数据类型)
- 使用泛型的接口,公共抽象方法可以用泛型(静态修饰的成员不能使用泛型)
- 实现 使用泛型的接口的类,在类和接口后都需要加泛型,但是一般使用匿名内部类创建接口实例
eg01:在方法中使用
public class Test {
public static void main(String[] args) {
Integer i = test(1);
String str = test("123");
Test t = new Test();
Test test = test(t);
}
/** * 要求,传入的参数类型就是返回值类型 * 泛型在使用时,接收到的是什么数据类型,此泛型就是什么数据类型 */
public static <X> X test(X str) {
return str;
}
/** * 可以传入任何一种类型 */
public static <X,Y> void test01(X str,Y y,Y y2) {
}
}
eg02:在类中使用
- 类上定义泛型,必须在类名之后继承与实现之前,紧随类名
- 泛型在使用时,接收到的是什么数据类型,此泛型就是什么数据类型
/** * 类上定义泛型,必须在类名之后继承与实现之前,紧随类名 */
class Person<K,Y,Z> extends Object {
private K k;
private Y y;
private Z z;
private String str;
public Person() {
super();
}
public Person(K k, Y y, Z z, String str) {
super();
this.k = k;
this.y = y;
this.z = z;
this.str = str;
}
public class Test02 {
public static void main(String[] args) {
//泛型在使用时,接收到的是什么数据类型,此泛型就是什么数据类型
Person<Integer, String, Boolean> person = new Person<Integer, String, Boolean>();
Person<String, Integer, Integer> person2 = new Person<String, Integer, Integer>();
}
}
eg03:在接口中使用
public class Test03 {
public static void main(String[] args) {
//1.匿名内部类使用泛型
MyInterfaceTest<String> test = new MyInterfaceTest<String>();
new MyInterface<Integer>() {
@Override
public void test01(Integer k) {
// TODO Auto-generated method stub
}
@Override
public Integer test02(Integer k) {
// TODO Auto-generated method stub
return null;
}
};
}
}
interface MyInterface<K>{
void test01(K k);
K test02(K k);
}
//2.类实现泛型接口
/*接口和实现类后都需要增加泛型 */
class MyInterfaceTest<K> implements MyInterface<K>{
@Override
public void test01(K k) {
// TODO Auto-generated method stub
}
@Override
public K test02(K k) {
// TODO Auto-generated method stub
return null;
}
}
2.集合
(1)概念
存储一组数据类型相同的数据(引用数据类型),长度可变
(2)体系层级
(3)Collection:接口(集合一级父类)
Collection:接口
特点:无序(存入顺序与取出顺序不一致),无下标
方法:
增
boolean add(E e):添加一个数据
boolean addAll(Collection<? extends E> c):将子集合中数据添加到集合中
删
boolean remove(Object o);:删除一个数据
boolean removeAll(Collection<?> c):将子集合中所有数据从集合中删除
void clear():清空
改
无
查
int size():获取集合中元素的个数
boolean contains(Object o):判断指定元素是否在集合中存在
boolean containsAll(Collection<?> c):判断子集合中所有数据是否在集合中存在
Iterator<E> iterator():迭代器
其他
boolean isEmpty():判断集合中是否存在元素
Object[] toArray():将集合转换为数组
(4)List:子接口(集合二级父类)
List:子接口
特点:有序,有下标
子类特有方法(除去继承Collection的方法)
增
一次插入一个数据,1参:插入的位置,2参:插入的数据
void add(int index, E element);
一次插入一组数据,1参:插入的位置,2参:插入的数据
boolean addAll(int index, Collection<? extends E> c);
删
按照下标删除指定位置的数据
E remove(int index);
改
修改:1参:下标,2参:修改后的元素
E set(int index, E element);
查
获取指定位置的元素,参数:下标
E get(int index):
(5)Set:子接口(集合二级父类)
Set
特点:无序(存入顺序与取出顺序不一致,但存储到其内部输出是有序的(由大到小或由小到大)),无下标,不能重复
子类特有方法:无(除去继承Collection方法,没有其他自己的方法)
(6)子接口实现类(集合)
List子接口实现类
(1)ArrayList jdk1.2,线程不安全
数据结构:数组
特点:查询速度快,增删速度慢
(2)Vector jdk1.0,线程安全的
数据结构:数组
(3)LinkedList jdk1.2,线程不安全
数据结构:链表
特点:增删速度快,查询速度慢
Set子接口实现类
(1)HashSet jdk1.2,线程不安全
数据结构:链表+红黑树(基于哈希表)
(2)LinkedHashSet jdk1.4,线程不安全
数据结构:链表+红黑树(基于哈希表,jdk源码封装实现)+链表
特点:有序
(3)TreeSet
数据结构:链表+红黑树(需要自己实现)
方案1:
数据自身拥有比较性
步骤1:让存储的数据所属的类实现Comparable接口
步骤2:重写compareTo方法
方案2:
提供比较器
创建TreeSet对象时,传入比较器的对象Comparator接口实现类
(7)迭代遍历
- 获取到集合的迭代器
- hasNext() 方法判断其要迭代的位置是否含有元素
- iterator.next()获取到迭代器指示位置的元素,并将迭代器指示位置向下移一个位置
- 如此循环,直到迭代器中元素遍历完毕
//迭代遍历
Iterator<Person> iterator=treeSet.iterator();
while(iterator.hasNext()) {
Person person=iterator.next();
System.out.println(person);
}
3.集合实现自定义排序
(1)Comparable接口
- 在java的jdk中提供了Comparable接口,其提供了一个抽象方法compareTo(T o),其中T代表泛型,将其与集合使用可以实现自定义排序
- java的8中基本数据类型均实现类Comparable接口,实现类其中的方法
1.以TreeSet为例,分析Comparable接口,进而实现自定义排序
- Person实现Comparable接口
- 重写compareTo(Person o)方法
其中方法中 this 代之集合中add(e)的值,将其依次与集合中原有的元素比较,确定其位置在存储数据的 数据结构 中的位置,进而插入数据结构中(使用某种数据结构实现数据值的按序存储)
- TreeSet其存储是红黑树,jdk中没有实现其排序方法,需要自己实现,使其存储的类实现Comparable接口是实现其排序的方法之一
public class Person implements Comparable<Person> {
private String name;
private String sex;
private int age;
private int height;
public Person() {
super();
}
public Person(String name, String sex, int age, int height) {
super();
this.name = name;
this.sex = sex;
this.age = age;
this.height = height;
}
/* ............省略了标准类的其他方法 */
//自定义比较
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
if (this.height!=o.height) {
return this.height-o.height;
}else if (this.age!=o.age) {
return this.age-o.age;
}
else {
return this.name.compareTo(o.name)+this.sex.compareTo(o.sex);
}
}
}
(2)Comparator接口
- Comparator接口中提供了compare(T o1, T o2)抽象方法,其中T代表泛型,其可以配合集合使用,实现集合的自定义排序
2.以TreeSet为例,分析Comparator接口,进而实现自定义排序
- 其可以看作是自定义比较器,在操作中使用,不需要对其操作对象的类进行实现接口
- 在创建TreeSet集合时,传入比较器(Comparator接口的实现类),下面使用匿名内部类的方式创建传入
compare(T o1, T o2)方法在使用时,其o1参数代表集合正在add(e)的对象,o2代表集合中原有的对象元素,将o1其依次与集合中原有的元素(o2)比较,确定其位置在存储数据的 数据结构 中的位置,进而插入数据结构中(使用某种数据结构实现数据值的按序存储)
- TreeSet其存储是红黑树,jdk中没有实现其排序方法,需要自己实现,在创建TreeSet对象时,传入自定义比较器(Comparator接口实现类)是实现其集合有序排序的方法之一
TreeSet<Person01> treeSet=new TreeSet<Person01>(new Comparator<Person01>() {
//实现比较器
@Override
public int compare(Person01 o1, Person01 o2) {
// TODO Auto-generated method stub
if (o1.getHeight()!=o2.getHeight()) {
return o1.getHeight()-o2.getHeight();
}
else if (o1.getAge()!=o2.getAge()) {
return o1.getAge()-o2.getAge();
}
else {
return o1.getName().compareTo(o2.getName())+o1.getSex().compareTo(o2.getSex());
}
}
});
(3)Comparable接口与Comparator接口的区别
Comparable接口
- 可以将其看作是小学时由高到低排座位,其排序方式是自己与别人去比较,确定你的位置
- 抽象为代码中就是,add(e)的对象与集合中已经存在的对象进行比较,确定add(e)的对象在底层数据结构中存储的位置
Comparator接口
- 可以将其看作是小学时由高到低排座位,其排序方式是老师给你们两两比较,然后再确定你的位置
- 抽象为代码中就是,add(e)的对象与集合中已经存在的对象进行比较,其内部的compare(T o1, T o2)方法中,o1代表add(e)的对象,o2代表合中已经存在的对象,将其两两比较确定add(e)的对象在底层数据结构中存储的位置
(4)操作集合的工具类:Collections(实现自定义排序)
- 常用方法
Collections.sort(list);//排序
Collections.reverse(list);//翻转
Integer max = Collections.max(list);//寻找最大值
Integer min = Collections.min(list);//寻找最小值
- Collections中sort方法
public static <T extends Comparable<? super T>> void sort(List<T> list)
public static <T> void sort(List<T> list, Comparator<? super T> c)
以上两个方法是Collections提供的两个重载的sort方法,从其参数可以看出其实现集合排序的两种方式也是和Comparable和Comparator有关,即若想使用此工具类实现对集合的排序有两种方式:
方案一:集合中存储的数据类型自身拥有比较性
调用Collections.sort(list)
对list集合进行排序时,要求list集合中村存储的数据类型的类实现了Comparable接口,并重写了其中的comparaTo方法方案二:提供自定义比较器
调用Collections.sort(list,new Comparator(compara的实现方法))
对list集合进行排序时,1参代表要排序的集合,2参代表自己创建的比较器(提供实现了Comparator接口的实现类,要求其重写了compara接口)
使用工具类Collections实现对集合排序的代码,可以参考我的另一篇博客:
JAVA_自定义排序(Comparable、Comparator)详解
4.双列集合(Map)
(1)概念
概念: 存储一组数据类型相同的数据,长度可变
存储数据的要求: 键值对应
(2)体系层级
Map(接口)
- HashMap(类)
特点: 链表+红黑树(哈希表),线程不安全,1.2
-------在其内部是以键值Key 由小到大排序的- HashTable(类)
特点: 链表+红黑树(哈希表),线程安全,1.0
-------在其内部是以键值Key 由小到大排序的
Properties(类)- TreeMap(类)
特点: 链表+红黑树(需要自己提供)
-------在其内部没有进行默认的排序,需要存储数据自身具有比较性或提供比较器
注意: TreeMap存储数据, 键(key) 要么拥有比较性,要么在创建TreeMap时传入比较器(类似TreeSet集合)
(3)Map的方法
增
V put(K key, V value);
注意:如果字典中key不存在,则是添加,如果key存在,那么将修改key对应的value
void putAll(Map<? extends K, ? extends V> m);
删
V remove(Object key);
void clear();
改
V put(K key, V value);
查
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
其他:
Entry
getKey();
getValue();
(4)Map的遍历
Set<Integer> keySet = hashMap.keySet();
//遍历方式1
for (Integer key : keySet) {
String value=hashMap.get(key);
System.out.println(key+","+value);
}
//遍历方式2
Set<Entry<Integer,String>> entrySet = hashMap.entrySet();
for (Entry<Integer, String> entry : entrySet) {
int key=entry.getKey();
String value=entry.getValue();
System.out.println(key+","+value);
}
边栏推荐
- A way of writing SQL, update when matching, or insert
- If the college entrance examination goes well, I'm already graying out at the construction site at the moment
- Matlab learning notes
- Introduction au GPIO
- Operation test of function test basis
- 一图看懂对程序员的误解:西方程序员眼中的中国程序员
- 英雄联盟|王者|穿越火线 bgm AI配乐大赛分享
- Advanced learning of MySQL -- basics -- transactions
- DAY ONE
- "Latex" Introduction to latex mathematical formula "suggestions collection"
猜你喜欢
AI超清修复出黄家驹眼里的光、LeCun大佬《深度学习》课程生还报告、绝美画作只需一行代码、AI最新论文 | ShowMeAI资讯日报 #07.06
X.509 certificate based on go language
Core knowledge of distributed cache
How to set encoding in idea
Racher integrates LDAP to realize unified account login
Introduction au GPIO
Three application characteristics of immersive projection in offline display
48页数字政府智慧政务一网通办解决方案
Memory optimization of Amazon memorydb for redis and Amazon elasticache for redis
On February 19, 2021ccf award ceremony will be held, "why in Hengdian?"
随机推荐
Rails 4 asset pipeline vendor asset images are not precompiled
智能运维应用之道,告别企业数字化转型危机
File and image comparison tool kaleidoscope latest download
Pdf document signature Guide
Model-Free Control
【YoloV5 6.0|6.1 部署 TensorRT到torchserve】环境搭建|模型转换|engine模型部署(详细的packet文件编写方法)
Advanced learning of MySQL -- basics -- multi table query -- subquery
Use source code compilation to install postgresql13.3 database
Leecode brushes questions and records interview questions 01.02 Determine whether it is character rearrangement for each other
Understand the misunderstanding of programmers: Chinese programmers in the eyes of Western programmers
kubernetes部署ldap
Geo data mining (III) enrichment analysis of go and KEGG using David database
Mujoco second order simple pendulum modeling and control
How engineers treat open source -- the heartfelt words of an old engineer
Supersocket 1.6 creates a simple socket server with message length in the header
rancher集成ldap,实现统一账号登录
Notes of training courses selected by Massey school
Interface master v3.9, API low code development tool, build your interface service platform immediately
沉浸式投影在线下展示中的三大应用特点
Memory optimization of Amazon memorydb for redis and Amazon elasticache for redis