Java集合框架
数组:数据类型相同,内存空间连续,长度固定
Java集合框架:Java中提供的各种集合的统称
集合特点:
1.长度是随意的,动态变化
2.集合只能存储引用数据类型,也可以存基本数据类型(存储时自动装箱)
部分集合底层是由数组实现的
Set—/— HashSet
/ — HashTree
Collection—–
\ Vector — Stack
\ /
List—— LinkedList
ArrayList
ArrayList
底层由数组实现,查询快,增删慢,线程不安全,效率高
ArrayList arr = new ArrayList();
arr.add(1);//添加元素
arr.add(索引,值);//追加元素
//add方法如果是List集合一直返回true,因为List集合可以存储重复元素;
//如果是Set集合,当存储重复元素时,会返回false;
arr.size();//长度
arr.remove(1);//删除(如果是数字默认为索引,不会自动装箱)
arr.clear();//移除所有元素
arr.addAll(arr2);把另外一个集合加到此集合中
arr.isEmpty();//是否为空 返回布尔值
arr.contains(元素);//元素是否在集合中
arr.containsAll(arr2);//判断调用的集合是否包含传入的集合
arr.removerAll();删除交集
arr.retainAll(arr2);//取交集,把交集赋给arr,如果arr没有改变返回false.改变了返回true
arr.get(1);取到索引1 的元素
arr.set(1,"aaaa");用aaaa替换索引1的元素;
List arrNew = arr.subList(start,end);返回指定start-to的集合
List.toArray();//转化为数组
集合的长度是由添加的元素个数决定的,与初始化的长度无关
特点:
1)有序,根据添加的顺序决定
2)可重复,不唯一
3)空间连续
遍历集合
//1
for(int i = 0; i < arr.size();i++){
System.out.println(arr.get(i));
}
//2
for(Object o:ary){
System.out.println(o.toString);
}
//3迭代器
Iterator it = ary.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
适用场合:遍历操作频繁时(内存空间连续)
//listIterator是list特有的
ListIterator lit = list.listIterator();
while(lit.hasNext()){
String str = (String)lit.next();
if("word".equals(str){
lit.add("javaee");//可以在遍历的同时增加元素,并发修改ConcurrentModificationException
}
}
lit.hasPrevious();//指针位置是否有前一个元素;直接用的话指针在第一个位置,没有前一个元素,所以要hasNext()遍历移动指针后才能用,所以说压根儿没什么用吧
数组转集合:
int[] arr= {11,22,33};
List list = Arrays.asList(arr);//基本数据类型的数组转换成集合,会将整个数组当做一个元素
Integer[] arr1 = {11,22,33,44};
List<Integer> list = Arrays.asList(arr);
集合转数组:
ArrayList<String> List = new ArrayList<>();
String[] arr = list.toArray(new String[10]);//当集合转数组时,数组长度如果小于等于集合的size,转换后的数组长度等于集合size;如果数组长度大于size,数组长度等于分配的size;
LinkedList
链表:有序,可重复,空间不连续,查询慢,增删快.
可以使用List接口的方法.扩展了3对 6个方法
适用于频繁增删
不适用频繁遍历
由于内存空间不连续,头部尾部操作方法比通过索引操作效率高
public class LinkedTest {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add("aa");
ll.add("bb");
ll.addFirst("cc");//头部元素
System.out.println(ll.getFirst());//得到头部元素
ll.removeFirst();//删除头部元素
ll.addLast("dd");//尾部元素
System.out.println(ll.getLast());//得到尾部元素
ll.removeLast();//删除尾部元素
}
}
Vector
用法及存储结构和ArrayList相同,是一个古老的集合
底层由数组实现,查询快
Vector线程安全,效率低
ArrayList线程不安全,效率高
Vector v = new Vector();
v.addElement("a");
Enumeration en = v.elements(); //获取枚举
while(en.hasMoreElements()){ //判断集合中是否有下一个元素
System.out.println(en.nextElement()); //获取元素
}
泛型集合
List下的集合:
1.存入的数据都会转换为Object
2.取出数据时容易发生异常
使用泛型集合来提升集合的安全性:
泛型集合是对集合中存放数据的类型的约束,非约定的类型
提高安全性,省去强转的麻烦.
1.7新特性:前面写了泛型后面写<>即可
<>中存放的必须是引用类型
//LeetCode上的
// "static void main" must be defined in a public class.
public class Main {
public static void main(String[] args) {
// 1. initialize
List<Integer> v0 = new ArrayList<>();
List<Integer> v1; // v1 == null
// 2. cast an array to a vector
Integer[] a = {0, 1, 2, 3, 4};
v1 = new ArrayList<>(Arrays.asList(a));
// 3. make a copy
List<Integer> v2 = v1; // another reference to v1
List<Integer> v3 = new ArrayList<>(v1); // make an actual copy of v1
// 3. get length
System.out.println("The size of v1 is: " + v1.size());;
// 4. access element
System.out.println("The first element in v1 is: " + v1.get(0));
// 5. iterate the vector
System.out.print("[Version 1] The contents of v1 are:");
for (int i = 0; i < v1.size(); ++i) {
System.out.print(" " + v1.get(i));
}
System.out.println();
System.out.print("[Version 2] The contents of v1 are:");
for (int item : v1) {
System.out.print(" " + item);
}
System.out.println();
// 6. modify element
v2.set(0, 5); // modify v2 will actually modify v1
System.out.println("The first element in v1 is: " + v1.get(0));
v3.set(0, -1);
System.out.println("The first element in v1 is: " + v1.get(0));
// 7. sort
Collections.sort(v1);
// 8. add new element at the end of the vector
v1.add(-1);
v1.add(1, 6);
// 9. delete the last element
v1.remove(v1.size() - 1);
}
}
Set
无序,不能重复,没有索引
无序:存放的顺序和遍历取出的顺序不一致;
HashSet:根据哈希表存储
TreeSet:根据二叉树存储
值唯一性的原理分析:判断的是对象的存放地址,存放时,首先获取地址的hashCode()值,根据hashcode判断是否重复.
可以重写类的hashcode方法,根据自定义的属性值产生hashcode
Java判断对象是否相同的过程:
1.先判断hashCode();如果hashCode不同,加入集合中;
如果hashCode不同,进一步判断equals
2.重写equals()
setStu.add(stu1);
自动调用stu1对象的hashCode(),系统自动判断此hashCode值在HashSet集合中是否已经存值
如果没有存值,则存入到HashSet中
如果有,再次调用eqals()方法,根据equals返回的结果true
:值相同,不添加到HashSet
false :值不同,则添加到HashSet
Map:无索引
提供key-value的存储方式
键 值 对
CN - 中华人民共和国
USA - 美国
JP -日本
共同特点:无序
key唯一(key重复后,会进行覆盖)
重点:Map集合的遍历
Map 接口
实现类:HashMap HashTable TreeMap(可以自动以排序规则)
总结:集合框架
一:Collection
1.1、List
ArrayList:内存连续 有序 可重复
Vector:线程安全,效率低
LinkedList: 有序 可重复 内存不连续 6个方法
1.2、Set :不连续 无索引 无序 唯一
HashSet:Hash表结构存放数据
子类LinkedHashSet 有序
TreeSet:以Tree结构存放数据
由于实现了SortedSet接口,可以自定义排序规则
二:Map:无索引 无序 key唯一 value可重复
2.1、HashMap
LinkedHashMap有序
2.2、HashTable
2.3、TreeMap 实现了SortedMap接口,可以自定义排序规则
三:Collections 封装了工具类
辅助操作集合
类集框架
1.类集框架是一组类和接口
2.位于java.util包当中
3.主要用于存储和管理对象
4.主要分为三大类–集合,列表,映射;
集合(Set)
集合中的对象不按特定方式排序,并且没有重复对象.
继承了Collection接口.有一个实现类HashSet
public class Test{
public static void main (String[] args){
Set<String> set = new HashSet<String>();
set.add("a");//添加元素
set.add("b");
set.add("a");//重复的元素会被忽略掉
System.out.println(set.size());//长度
set.remove("a");//删除a元素
set.clear();//清除
set.isEmpty();//返回值为布尔值,是否为空
//Iterator<---Collection<---Set<---HashSet
// <---List<---ArrayList
//Iterator:hasNext(); next();
//调用Set对象的Iterator方法,会生成一个迭代器对象,该对象用于遍历整个Set
Iterator<String> it = set.iterator();
while(it.hasNext()){
String s = it.next();//判断当前游标位置有没有下一个元素
System.out.println(s);//把当前游标的下一个元素取出来并将游标移动到下一个位置
}
}
}
列表(List)
集合中对象按照索引位置排序,可以有重复的对象.
映射(Map)
集合中的每一个元素包含一个键对象和一个值对象,键不可以重复,值可以重复.每一个元素都是一个键值对
HashMap是Map的实现类
Map<String,String> ary = new HashMap<>();
ary.put("去","死") //添加一个元素,如果key重复,覆盖之前的
ary.get("去"); //通过键找值
Collection接口
Hash算法
输入数据,通过hash算法得到一个唯一的散列值.
存储数据,数据与散列值关联.查找数据
equals
== 比较两个引用指向的地址.
equals比较对象的内容.通常在重写后:
1)对象的类型相等(intanceof比较)
2)两个对象的成员变量的值完全相等
重写equals方法
public boolean equals(Object o){
if(this == o){
return true;
}
if(o instanceof User){
User u = (User)o;
if(this.age == u.age && this.name.equals(u.name)){//name调用的equals方法
return true;
}else{
return false;
}
}else{
return false;
}
}