第10篇-JAVA 集合框架-JAVA 泛型

2022-03-11 11:31 更新
  • 每篇一句 :所有的不甘,都是因为还心存梦想
  • 初学心得: 不是每件事都注定会成功,但是每件事都值得一试
  • (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-15| JAVA 集合框架/JAVA 泛型 ]

1.JAVA 集合框架概念

通俗的说,集合就是一个存放数据的容器,准确的说,就是放数据对象引用的容器
数组和集合都是容器,有何不同?
数组长度固定,集合长度可变
数组只能存放相同类型的数据,集合可以存放不同类型的数据
数组可存放简单数据类型和类类型的数据,集合只能存放类类型数据
JAVA集合框架:java中用来表示集合,和操作集合的所有类库的统称
JAVA中的集合从大方向分有两种:Collection 集合,Map 集合,它们都继承自Object
Alt text
Collection又有两个分支
1.List(列表),2.Set(集合),List和Set也都是接口
List接口的特点: 集合中的元素有顺序,能重复

集合中分为三大接口:
Collcction、Map(映射)、Itcrator(迭代的父类接口)
集合框架的接口和类在java.util包中
Collcction分支为两个子接口list(列表接口),set(集合接口)

集合框架List接口
有序的接口,此接口的用户可以对列表中的每个元素的插入位置进行
精确的控制,用户可以根据元素的整数索引(在列表中的位置)访问元素,并索列表中的元素
List实现类ArrayListVectorLinkedList
1.ArrayList是底层用数组实现的List
特点:查询效率高,增删效率低, 线程不安全
2.LinkedList是底层用双向循环链表实现的List
特点:查询效率低,增删效率高
3.Vector: 底层用数组实现List接口的另一个类
特点:重量级,占据更多的系统开销,线程安全

集合框架Set接口
Set接口特点是集合中的元素无顺序(存入和取出的顺序不一定一致),不能重复
Set接口一个不包含重复元素的collection,更确切的讲,set不包含满足e1.equal(e2)的元素
对e1和e2,并且最多包含一个null元素,正如其名称所暗示的,此接口模仿了数学上的set抽象
HashSet类实现Set接口,由哈希表(实际上是一个HashMap实例)支持,它不保证set的迭代顺序,特别是它不保证该顺序恒久不变,此类允许使用null元素
TreeSetLinkedHashSet

Set和List的区别
● 1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素
● 2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet&
● 3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector&
Set分支的常用类有:HashSet,TreeSet
1.HashSet:底层数据结构是哈希表
特点:增、删集合中的元素速度快
2.TreeSet集合中的元素除了没有顺序和不能重复外,还会自然排序,这便是该集合的特点

集合框架Map接口
Map接口
特点:K与V,键值对,映射所维护的键的类型,映射值得类型
将键映射到值得对象,一个映射不能包含重复的键,每个键最多只能映射一个值
HashMapHashtableTreeMapLinkedHashMap
1.HashMap:特点:线程不安全 允许key或者value是null值
2.TreeMap特点:按照键值排序,线程不安全

2.JAVA 集合实现类(集合类)

Java提供了一套实现了Collection接口的标准集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现

| 序号 | 类描述 |
| :-------- | --------:|
| 1 | AbstractCollection 实现了大部分的集合接口 |
| 2 | AbstractList 继承于AbstractCollection 并且实现了大部分List接口 |
| 3 | AbstractSequentialList 继承于 AbstractList ,提供了对数据元素的链式访问而不是随机访问 |
| 4 | LinkedList该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:Listlist=Collections.synchronizedList(newLinkedList(...));LinkedList 查找效率低 |
| 5 | ArrayList该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低 |
| 6 | AbstractSet 继承于AbstractCollection 并且实现了大部分Set接口 |
| 7 | HashSet该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个 |
| 8 | LinkedHashSet具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现 |
| 9 | TreeSet该类实现了Set接口,可以实现排序等功能 |
| 10 | AbstractMap 实现了大部分的Map接口 |
| 11 | HashMap HashMap 是一个散列表,它存储的内容是键值对(key-value)映射,该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步 |
| 12 | TreeMap 继承了AbstractMap,并且使用一颗树 |
| 13 | WeakHashMap 继承AbstractMap类,使用弱密钥的哈希表 |
| 14 | LinkedHashMap 继承于HashMap,使用元素的自然顺序对元素进行排序 |
| 15 | IdentityHashMap 继承AbstractMap类,比较文档时使用引用相等 |

3.迭代器

什么是迭代器?迭代器就是取出集合元素的方式
遍历一个集合中的元素,例如,显示集合中的每个元素
一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或ListIterator接口
迭代器,使你能够通过循环来得到或删除集合的元素
ListIterator 继承了Iterator,以允许双向遍历列表和修改元素

迭代器方法:
使用 Java Iterator,通过实例列出Iterator和listIterator接口提供的所有方法

遍历 ArrayList:



public class Demo{
public static void main(String[] args) {
List<String& list=new ArrayList<String&(); //实例化List集合
list.add("Hello"); //添加元素
list.add("World");
list.add("HAHAHAHA");
//第一种遍历方法使用foreach遍历List
for (String str : list) {
//也可以改写for(int i=0;i<list.size();i++)这种形式
System.out.println(str);
}
//第二种遍历,把链表变为数组相关的内容进行遍历
String[] strArray=new String[list.size()];
list.toArray(strArray);
for(int i=0;i<strArray.length;i++) //这里也可以改写为 foreach(String str:strArray)这种形式{
System.out.println(strArray[i]);
}
//第三种遍历 使用迭代器进行相关遍历
Iterator<String& ite=list.iterator();
while(ite.hasNext()){ //判断下一个元素之后有值
System.out.println(ite.next());
}
}
}

三种方法都是用来遍历ArrayList集合
第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度

遍历 Map:


public class Demo2{
public static void main(String[] args) {
Map<String, String& map = new HashMap<String, String&(); //实例化Map集合
map.put("1", "value1"); //添加元素
map.put("2", "value2");
map.put("3", "value3");
//NO1.:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for (String key : map.keySet()) {
System.out.println("key= "+ key + " and value= " + map.get(key));
}
//NO2.
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator<Map.Entry<String, String&& it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String& entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//NO3.:容量大时推荐使用此方法
System.out.println("通过Map.entrySet遍历key和value");
for (Map.Entry<String, String& entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//NO4.
System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
for (String v : map.values()) {
System.out.println("value= " + v);
}
}
}

集合是一个对象,可容纳其他对象的引用。集合接口声明对每一种类型的集合可以执行的操作,集合框架的类和接口均在java.util包中
任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换

4.JAVA 泛型

泛型的本质是参数化类型,所操作的数据类型被指定为一个参数
泛型方法:方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用
定义泛型方法的规则
● 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前
● 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用指定一个泛型类型名称的标识符
● 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符
● 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型

public class Demo3{
// 泛型方法 printArray
public static < E & void printArray( E[] inputArray ){
// 输出数组元素
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}

public static void main( String args[] ){
// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println( "整型数组元素为:" );
printArray( intArray ); // 传递一个整型数组
System.out.println( "\n双精度型数组元素为:" );
printArray( doubleArray ); // 传递一个双精度型数组
System.out.println( "\n字符型数组元素为:" );
printArray( charArray ); // 传递一个字符型数组
}
}



泛型类
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分
和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符,接受一个或多个参数,这些类被称为参数化的类或参数化的类型

public class Demo4<T& {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Demo4<Integer& integerDemo = new Demo4<Integer&();
Demo4<String& stringDemo = new Demo4<String&();
integerDemo.add(new Integer(10));
stringDemo.add(new String("泛型类"));
System.out.printf("整型值为 :%d\n\n", integerDemo.get());
System.out.printf("字符串为 :%s\n", stringDemo.get());
}
}

初学(JAVA 集合框架/JAVA 泛型 高级阶段) 难点: ★★★★★

希望每一篇文章都能够对读者们提供帮助与提升,这乃是每一位笔者的初衷

感谢您的阅读 欢迎您的留言与建议

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号