1.Java集合分为Collection和Map
2.Collection分为:List(Vector ArrayList LinkedList)、Set(HashSet LinkedSet TreeSet)
AarrayListpackage collection;
import java.util.ArrayList;
public class Collection {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
//add:添加单个元素
arrayList.add("jack");
arrayList.add(10);
arrayList.add(true);
System.out.println("arrayList="+arrayList);
//remove删除元素
// arrayList.remove(0);//删除第一个元素
arrayList.remove("jack");//指定删除某个对象
System.out.println("arrayList="+arrayList);
//contains:查找元素是否存在
System.out.println(arrayList.contains("jack"));//false,因为删除了元素jack
//获取元素个数
System.out.println(arrayList.size());//2
//isEmpty:判断是否为空
System.out.println(arrayList.isEmpty());//false
//clear:清空
arrayList.clear();
System.out.println(arrayList);//[]
//addAll:添加多个元素
ArrayList arrayList2 =new ArrayList();
arrayList2.add("p");
arrayList2.add("l");
arrayList2.add("y");
arrayList.addAll(arrayList2);
System.out.println(arrayList);//[p, l, y]
//containsAll:查找多个元素
System.out.println(arrayList.containsAll(arrayList2));//true
//removeAll:删除多个元素
arrayList.add(19);
arrayList.removeAll(arrayList2);
System.out.println(arrayList);
}
}
1.1List接口方法
1.集合元素有序,可以重复
2.每个元素都有对应顺序的索引
3.List容器中的元素都对应一个整数型的序号记载其在容器的位置,可以根据序号存取容器中的元素
package collection;
import java.util.ArrayList;
public class List {
public static void main(String[] args) {
ArrayList List1 = new ArrayList();
List1.add("JACK");
List1.add("sparrow");
List1.add("Tom");
List1.add("Tom");
System.out.println("List1="+List1);//List1=[JACK, sparrow, Tom, Tom]
System.out.println(List1.get(0));//取出第一个元素,索引是从0开始的
}
}
操作集合元素的方法
package collection;
import java.util.ArrayList;
import java.util.List;
public class ListMethod {
public static void main(String[] args) {
List List1 = new ArrayList();
List1.add("q");
List1.add("w");
List1.add(1,"p");//在index=1,也就是q中插入"p",插入一个元素
System.out.println(List1);//[q, p, w]
ArrayList List2 = new ArrayList();
List2.add("S");
List2.add("a");
List1.addAll(1,List2);//在q中插入S,a,插入多个元素
System.out.println(List1);//[q, S, a, p, w]
System.out.println(List1.get(2));//获取指定位置元素,这里是第三个元素位置也就是a
System.out.println(List1.indexOf("a"));//2 a在集合中首次出现的位置
System.out.println(List1.lastIndexOf("w"));//4 w在集合中末次出现的位置
List1.remove(2);//删除一个元素值,在这里是删除了一个
System.out.println(List1);
List1.set(2,"e");//将第三个元素值替换成e
System.out.println(List1);
//List returnlist=List1.subList(1,3);//返回的是下标1和下标(3-1)也就是下标2
List1.subList(1,3);
// System.out.println("returnlist="+returnlist);
System.out.println(List1.subList(1,3));
}
}
1.2List三种遍历方式
1)方式一:使用iterator
Iterator iter = col.iterator();
while(iter.hasNext()){
Object o = iter.next();
}
2)方式二:使用增强for
for(Object o:col){
}
3)方式三:使用普通for
for(int i=0;iTips:
使用LinkedList完成 使用方式和ArrayList一样
package collection; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListFor { public static void main(String[] args) { List List = new ArrayList(); List.add("jack"); List.add("p"); List.add("y"); List.add(10); //遍历 //1.迭代器 Iterator iterator = List.iterator(); while(iterator.hasNext()){ Object obj=iterator.next(); System.out.println(obj); } System.out.println("==========="); //2.增强for(用大写的I回车) for (Object o :List) { System.out.println("o="+o); } System.out.println("============="); //3.普通for循环 for(int i=0;i1.2.1 ArrayList 1.permits all elements,including null,ArrayList可以加入null,ArrayList可以加入null,并且有多个
2.ArrayList是由数组来实现数据存储的
3.ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码,在多线程情况下,不建议使用ArrayList
package collection; import java.util.ArrayList; @SuppressWarnings({"all"}) public class ArrayListDetail { public static void main(String[] args) { ArrayList arrayList = new ArrayList(); arrayList.add(null); arrayList.add("jack"); arrayList.add(null);//可以放多个空值 System.out.println(arrayList);//[null, jack, null] } }1.2.2 ArrayList底层结构和源码分析1)ArrayList中维护了一个Object类型的数组elementData. transient Object[]elementData;
2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData容量为1.5倍
3)若使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
1.3 Vector1)Vector类的定义说明
public class Vectorextends AbstractList implements List ,RandomAccess,Cloneable,Serializable 2)Vector底层也是一个对象数组,protected Object[] elenmentData;
3)Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
public synchronized E get(int index){ if(index>=elementCount) throw new ArrayIndexOutOfBoundsException(index); return elementData(index); }4)在开发中,需要线程同步安全时,考虑使用Vector
1.3.1 Vector底层结构和源码分析1.如果是无参,默认10,满后,就按2倍扩充,如果指定大小,则每次直接按2倍扩
package list; import java.util.Vector; public class Vector_{ public static void main(String[] args) { //无参构造器 Vector vector= new Vector(); for(int i=0;i<10;i++){ vector.add(i); } //源码解读 //1.new Vector()底层 } }1.4 LinkedList1.LinkedList底层实现了双向链表和双端队列特点
2.可以添加任意元素(元素可以重复),包括null
3.线程不安全,没有实现同步
1.4.1 LinkedList底层结构1.LinkedList底层维护了一个双向链表
2.LinkedList中维护了两个属性first和last分别指向 首节点和尾节点
3.每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。
4.所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高
5.模拟一个简单的双向链表
package list; public class LinkedList01 { public static void main(String[] args) { //模拟一个简单的双向链表 Node jack = new Node("jack"); Node Tom = new Node("Tom"); Node merry = new Node("merry"); //连接三个结点,形成双向链表 //jack->Tom->merry jack.next =Tom; Tom.next = merry; //merry->Tom->jack merry.pre = Tom; Tom.pre = jack; Node first = jack;//让first引用指向jack,就是双向链表的头 Node last = merry;//让last引用指向merry,双向链表的尾 } } //定义一个Node类,Node对象 表示双向链表的一个节点 class Node{ public Object item;//真正存放数据 public Node next;//指向后一个节点 public Node pre;//指向前一个节点 public Node(Object name){ this.item = name; } public String toString(){ return "Node name="+item; } }2.1 Set接口和常用方法1.Set接口基本介绍
1)无序,没有索引
2)不允许重复元素,所以最多包含一个null
2.Set接口常用方法
1)和List接口一样,也是Collection的子接口,因此,常用方法和Collection接口一样
3.Set接口遍历方法
1)可以使用迭代器
2)增强for
3)不能使用索引的方式来获取
package collection.set_; import javafx.beans.binding.ListExpression; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetMethod { public static void main(String[] args) { //1. 以Set接口的实现类 HashSet //2.set接口的实现类的对象(Set接口对象),不能存放重复元素,但可以有null //3.set接口对象存放数据是无序 //4.注意:取出的顺序是一定的虽然不是添加的顺序,但是是固定的 Set set = new HashSet(); set.add("john"); set.add("lucy"); set.add("john");//重复 set.add("jack"); set.add(null); set.add(null);//再次添加null System.out.println(set);//[null, john, lucy, jack] //遍历 //方式1:使用迭代器 Iterator iterator = set.iterator(); while(iterator.hasNext()){ Object obj=iterator.next(); System.out.println(obj); } //方式2:增强for for (Object o :set) { System.out.println("o="+o); } //set接口对象,不能通过索引来获取 } }2.1.1 HashSet1.实现了Set接口
2.HashSet实际上是HashMap
3.可以存放null值
4.HashSet不保证元素是有序的,取决于hash后,在确定索引的结果
5.不能有重复元素或对象
package collection.set_; import java.util.HashSet; public class HashSet01 { public static void main(String[] args) { HashSet set = new HashSet(); //1.在执行add方法后,会返回一个Boolean值 //2.添加成功为true 失败为false //3.可以通过remove指定删除对象 System.out.println(set.add("john")); System.out.println(set.add("jack")); System.out.println(set.add("merry")); System.out.println(set.add("john"));//如果添加失败会返回一个false//false set.remove("john"); System.out.println(set); } }2.1.2 HashSet底层机制1.HashSet底层是HashMap
2.添加一个元素时,先得到Hash的值,会转成->索引值
3.找到存储数据表table,看这个索引位置是否已经存放的有元素
4.如果没有,直接加入
5.如果有,调用equals比较,如果相同就放弃添加,如果不同就添加到最后
2.2 LinkedHashSet1.LinkedHashSet是HashSet的子类
2.LinkedHashSet底层是一个LinkedHashMap,底层维护了一个数组+双向链表
3.LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
4.LinkedHashSet不允许添加重复元素
package collection.set_; import java.util.LinkedHashSet; import java.util.Set; public class LinkedHashSetSource { public static void main(String[] args) { Set set = new LinkedHashSet(); set.add(new String("AA")); set.add(456); set.add(new Coustomer("li",1001)); set.add(123); System.out.println(set); } } class Coustomer{ private String name; private int id; public Coustomer(String name,int id){ this.name=name; this.id=id; } }2.3 TreeSetpackage collection.set_; import java.util.Comparator; import java.util.TreeSet; public class TreeSet_ { public static void main(String[] args) { //1.当使用无参构造器,创建treeSet,仍然是无序的 //2.将添加的元素按照字符串大小排序 //3.使用TreeSet提供的一个构造器,可以传入一个比较器(匿名内部类) //并指定排序规则 // TreeSet treeSet = new TreeSet(); TreeSet treeSet = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { //下面调用String的compareTo方法进行字符串大小比较 return ((String)o2).compareTo((String) o1); } }); //添加数据 treeSet.add("jack"); treeSet.add("tom"); treeSet.add("sp"); treeSet.add("y"); System.out.println(treeSet);//[y, tom, sp, jack] } }3.1 Map接口1.Map与Collection并列存在,用于保存映射关系的数据
2.Map中的key和Value可以是任何引用类型的数据,会封装到HashMap$Node对象中
3.Map中的key不允许重复
4.value可以重复
5.key可以为null,value也可以为null,且有多个,key为null只能有一个
6.常用String类作为key
7.key和Value之间存在单向一对一的关系
package map; import java.util.HashMap; import java.util.Map; public class Map_ { public static void main(String[] args) { Map map = new HashMap(); map.put("no1","zhang"); map.put("no2","han"); map.put("no1","peng");//用新的值替换zhang//结果为peng System.out.println(map);//{no2=han, no1=peng} } }3.2 Map常用方法(例子为HashMap):1.put :添加
2.remove:根据删除键删除映射关系
3.get:根据键获取值
4.size:获取元素个数
5.isEmpty:判断个数是否为0
6.clear:清除
7.containsKey:查找键是否存在
package map; import java.awt.print.Book; import java.util.HashMap; import java.util.Map; public class MapMethod { public static void main(String[] args) { //常用方法 Map map = new HashMap(); map.put("邓超",new Book1 ("",100)); map.put("邓超","孙俪");//替换了,也就是说邓超这个时候对应孙俪了而不是一本书 map.put("王金","马蓉"); map.put("张哲","马蓉"); map.put("刘星","null"); map.put("null","刘亦菲"); map.put("陆星","徐妍"); map.put("peng","X"); System.out.println(map);//{邓超=孙俪, null=刘亦菲, 王金=马蓉, 张哲=马蓉, 陆星=徐妍, 刘星=null} map.remove("邓超");//也可以写成"邓超","孙俪" System.out.println(map);//{null=刘亦菲, 王金=马蓉, 张哲=马蓉, 陆星=徐妍, 刘星=null} map.remove("null"); System.out.println(map);//{王金=马蓉, 张哲=马蓉, 陆星=徐妍, 刘星=null} map.get("王金"); System.out.println(map.get("王金"));//获取王金对应的值:马蓉 System.out.println(map.size());//获取元素个数:4 System.out.println(map.isEmpty());//判断个数是否为0:false // map.clear(); System.out.println(map);//{} System.out.println(map.containsKey("peng"));//如果不进行clear,为true,若进行,为false } } class Book1{ private String name; private int num; public Book1(String name,int num) { this.name = name; this.num = num; } }3.2.1 遍历方法public class MapMethod { public static void main(String[] args) { //常用方法 Map map = new HashMap(); map.put("邓超",new Book1 ("",100)); map.put("邓超","孙俪");//替换了,也就是说邓超这个时候对应孙俪了而不是一本书 map.put("王金","马蓉"); map.put("张哲","马蓉"); map.put("刘星","null"); map.put("null","刘亦菲"); map.put("陆星","徐妍"); map.put("peng","X"); //第一组先取出所有的Key,通过Key取出对应的Value Set keyset = map.keySet(); //(1)增强for System.out.println("======第一种方式======"); for (Object key: keyset) { System.out.println(key+"-"+map.get(key)); } //(2)迭代器 System.out.println("======第二种方式======"); Iterator iterator = keyset.iterator(); while(iterator.hasNext()){ Object key = iterator.next(); System.out.println(key+"-"+map.get(key)); } //第二组:把所有的values取出 Collection values = map.values(); //可以使用所有的Collection使用的遍历方法 //(1)增强for System.out.println("=====取出所有的value======"); for(Object value : values){ System.out.println(value); } //(2)迭代器 System.out.println("=====取出所有的value 迭代器===="); Iterator iterator2 = values.iterator(); while (iterator2.hasNext()){ Object value = iterator2.next(); System.out.println(value); } //第三组:通过EntrySet来获取k-v Set entrySet = map.entrySet(); //(1)增强for for(Object entry : entrySet){ //将entry转换成Map.Entry System.out.println(entry); } //(2)迭代器 Iterator iterator3 = entrySet.iterator(); while (iterator3.hasNext()){ Object entry = iterator3.next(); System.out.println(entry); }3.2.2 HashMap底层机制1.底层维护了Node类型的数组table,默认为null
2.当创建对象时,将加载因子初始化为0.75
3.当添加key-val时。通过key的哈希值得到在table的索引,然后判断是否有元素,如果没有直接添加,如果有,继续判断该元素的key是否和准备加入的key相等,如果相等,则直接替换成val;如果不相等需要判断是树结构还是链表结构,如果发现容量不足,则需要扩容
4.第一次添加,扩容table量为16,临界值为12
5.以后再扩容,则需要扩容table容量为原来的2倍,临界值为原来的2倍,也就是24
3.3 Hashtable 1.基本介绍(例子中包含Hashtable扩容)1)存放的元素是键值对:即K-V
2)hashtable的键和值都不能为null
3)hashTable使用方法基本上和HashMap一样
4)hashTable是线程安全的,hashMap是线程不安全的
package map; import java.util.Hashtable; public class HashTableExercise { public static void main(String[] args) { Hashtable table = new Hashtable(); table.put("john",100); // table.put(null,100);//显示异常 NullException // table.put("john",null);//显示异常 NullException table.put("lucy",100); table.put("lic",100); table.put("lic",88);//替换了,将以88替换成100 System.out.println(table); table.put("hello1",1); table.put("hello2",1); table.put("hello3",1); table.put("hello4",1); table.put("hello5",1); table.put("hello6",1); System.out.println(table); //Hashtable的底层 //1.底层有数组 Hashtable$Entry[] 初始化大小为11 //2.临界值 threshod 8 = 11 * 0.75 //3.扩容:按照自己的想法扩容进行就可以 } }3.4 TreeMappackage map; import java.util.Comparator; import java.util.TreeMap; public class TreeMap_ { public static void main(String[] args) { //使用默认构造器,创建TreeMap,是无序的 // TreeMap treeMap = new TreeMap(); TreeMap treeMap = new TreeMap(new Comparator() { @Override public int compare(Object o1, Object o2) { //按照传入的大小进行排序 return ((String)o2).compareTo((String)o1);//按照首字母顺序 t,s,k 从大到小 } }); // treeMap.put("jack",new Book2( "A",100)); treeMap.put("tom","汤姆"); treeMap.put("kris","克瑞斯"); treeMap.put("smith","史密斯"); System.out.println(treeMap); } } class Book2{ private String name; int price; public Book2(String name,int price){ this.name=name; this.price=price; } }



