1.集合概述
- java集合按照其存储结构可以分为两大类,一个是单列集合Collection和双列集合Map。
- Collection集合是单列集合的根接口,Collection中有两个重要的子接口:List和Set。
- Map集合是双列集合的根接口,用于存储具有键值对映射关系(key value)的元素
2.集合和数组的对比
- 长度:数组长度固定,集合长度可变(自动扩容)。
- 存储类型:数组可以存储基本数据类型,也可以存储引用数据类型;集合,只能存储引用数据类型。
3.List接口
- 概述: List集合的特点是元素有序、元素可重复;List接口继承自Collection接口,在List集合中允许出现重复的元素、所有的元素都是以一种线性方式存储的,程序中可通过索引(下标)来访问集合中的指定元素
- List的实现类有:ArrayList,LinkedList,vector(已淘汰)
4.ArrayList
- 概述:ArrayList集合类 是Collection接口的子接口List的实现类之一;ArrayList内部封装了一个长度可变的数组对象,当存入的元素超过数组的长度时,ArrayList会在内存中分配更大的数组来存储这些元素,故ArrayList可以看为是一个长度可变的数组。
- 底层是基于数组的,需要连续的内存
- 随机访问快,通过数组下标查询
- 尾部增删快,其他慢
- 线程不安全,效率高
5.ArrayList的成员方法
- add(E e) : 添加元素,返回值表示是否添加成功
- remove(E e) : 删除元素,返回值表示是否删除成功
- remove (int index):删除指定索引的元素,返回被删除的元素
- set(int index ,E e): 修改指定索引的元素,返回原来的元素
- get(int index): 得到指定索引的元素
- size() :返回集合的长度
package cn.sxau.集合;
import java.util.ArrayList;
public class ArraysListdemo1 {
public static void main(String[] args) {
ArrayList<String> arraysList = new ArrayList<>();
//添加元素 add(E e)
arraysList.add("zhnagsan");
arraysList.add("lisi");
arraysList.add("wnagwu");
for (int i = 0; i <arraysList.size(); i++) {
String s = arraysList.get(i);
System.out.println(s);
}
System.out.println("-----------------------------");
//查询
System.out.println("获取集合索引为0的元素:"+arraysList.get(0));
//获取长度
System.out.println("集合的长度为"+arraysList.size());
System.out.println("-----------------------------");
//删除
System.out.println("被删除的元素是"+arraysList.remove(0));//删除0索引的元素,并返回被删除的元素
System.out.println("遍历集合后,剩下的是:");
for (int i = 0; i <arraysList.size(); i++) {
String s = arraysList.get(i);
System.out.println(s);
}
System.out.println("-----------------------------");
//修改
System.out.println("被修改的元素是"+arraysList.set(1, "ddd"));//返回被修改的原来的元素
System.out.println("遍历集合:");
for (int i = 0; i <arraysList.size(); i++) {
String s = arraysList.get(i);
System.out.println(s);
}
}
}
6.ArrayList扩容规则
- 新数组长度 = 原数组长度/2+原数组长度
- 添加元素 add()
- 采用addAll(),添加元素,由于添加的是一个集合,所以第一次扩容的时候,应该在 扩容的默认长度和元素个数,选一个较大值。
7.LinkedList
-
底层是一个双向链表,无需连续的内存
-
随机访问慢,(根据链表遍历)
-
头尾插入删除快
-
线程不安全,效率高
7.2LinkedList的方法实现
package cn.sxau.Collection;
import java.util.LinkedList;
public class java_List_LinkedList {
public static void main(String[] args) {
/**
* 创建集合对象方式:
* 1.LinkedList list1 = new LinkedList();无需传递构造参数
* 2.LinkedList list2 = new LinkedList(list2);传递一个集合
*/
LinkedList linkedList = new LinkedList();
/**
* 添加:
* list.add("zhangsan"); //添加数据,放置在最后
* list.addFirst("数据"); //添加到最前面
* list.addLast("数据");//添加到最后
* list.add("","数据");//通过索引,添加数据
* list.add(集合)
* push("数据");//添加数据,直接添加到最前面
*/
linkedList.addFirst("张三");
linkedList.add("王五");
System.out.println(linkedList);
/**
* 查询
* list.get("索引");
* list.getFirst();
* list.getLast();
* element();//获取第一个数据
*/
System.out.println(linkedList.element());
System.out.println(linkedList.get(0));
/**
* 修改:
* set("索引","数据") 返回被修改的值;
*/
System.out.println(linkedList.set(0, "哈哈哈"));
System.out.println(linkedList);
/**
* 删除
* remove();
* removeFirst();
* removeLast();
* pop();弹出第一个数据,并返回
*/
System.out.println(linkedList.pop());
/**
* ArrayList有的方法,LinkedList基本也有
*/
}
}
8.线程安全是什么
-
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
-
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
9.Set接口
-
概述:Set系列的集合添加的元素是无序,不可重复的,无索引
-
Set实现类: HashSet,TreeSet, LinkedHashSet(继承于HashSet)
9.1 Set遍历方式
package cn.sxau.集合;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Set集合的遍历 {
public static void main(String[] args) {
/**
* Set的遍历
* 1.迭代器
* 2.增强for
*/
Set<String> set = new HashSet();//因为Set是一个接口不能实例化,所以使用多态(使用其实现类)创建
set.add("张三");
set.add("李四");
set.add("王五");
//打印集合
System.out.println(set); //展示的结果是无序的
/**
* 迭代器遍历
*/
Iterator<String> it = set.iterator();
while(it.hasNext()){
String next = it.next();
System.out.print(next+" ");
}
System.out.println();
/**
* 增强for循环,遍历Set
*/
for (String s: set
) {
System.out.print(s+" ");
}
}
}
9.2 TreeSet
特点:不重复,无索引,可排序(按照元素的默认规则排序)
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都好
9.2.1 TreeSet集合的默认排序规则
-
数值型:默认按照从小到大的顺序进行排序
-
字符,字符串:按照字符在ASCII表中的数字升序进行排序
package cn.sxau.集合;
import java.util.TreeSet;
public class TreeSet的排序 {
/**
* 利用treeSet存储整数并排序
*/
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(1);
ts.add(2);
ts.add(5);
ts.add(8);
ts.add(4);
//打印集合
System.out.println(ts); //默认排序规则,从小到大
}
}
9.2.2 TressSet的两种比较方式
- 方式一:默认排序:javabean类实现Comparable接口指定比较规则
- 方式二: 比较器排序:创建TreeSet对象的时候,传递比较器Comparator制定规则