● 集合概念
● 集合 API
● List 接口及实现类
● List接口集合迭代
● Set 接口
● Set 接口集合迭代
● Map 接口
● Collections类
1.集合概念
数组(容器):创建一个指定长度的数组,使用数组来存储多个数据,当程序运行时,数据数量是改变的,但是数组一旦给定,就不能改变,频繁的扩容是不可取的,数组的有点是查询速度快
集合(容器):对数组操作多种多样的,增删多,查询少,链表结构针对于程序中,这种有着不同的操作需求的存储,建议存储同一类型的数据
2.集合 API
3.List 接口及实现类
我们先说一说Collection 接口-定义了存取一组对象的方法,其子接口Set和List分别定义
了存储方式。
注意:
- Set 中的数据对象没有顺序且不可以重复。
- List 中的数据对象有顺序且可以重复。
ArrayList:List继承了Collection接口,有三个实现的类,底层是数组,查询快,但是增删慢
LinkedList:数组列表,数据采用数组方式存储,底层是链表,增删快,但查询慢
Vect:数组列表,添加同步锁,线程安全的
ArrayList的常用方法
- add(int index, E element)
- get(int index)
- indexOf(Object o)
- lastIndexOf(Object o)
- remove(int index) 删除并返回指定位置元素
- removeRange(int fromIndex, int toIndex) 删除指定区间的元素(子类继承使用)
- set(int index, E element)
// 集合(容器):
// 数组(容器):创建一个指定长度的数组,使用数组来存储多个数据,
// 程序运行时,数据运行时数据数量是改变的,但是数组一旦给定,就不能频繁的扩容,数组优点是查询速度快
// 对数据操作多种多样的,增删多,查询少,链表结构针对程序中,这种不同存储操作需求
// collection(单列)
// list(可重复)
// set(不可重复)
// Map(多列)
public static void main(String[] args) {
Collection<String> a=new ArrayList<>();
a.add("a");
a.add("b");
a.add("c");
a.add("d");
Collection<String> b=new ArrayList<>();
b.add("e");
b.add("f");
b.add("g");
b.add("h");
// a.addAll(b);//集合全部添加到另一个集合中
// a.clear();//将集合中的所有元素全部清空
// System.out.println( a.equals(b));//比较俩个集合中的元素是否相等
// System.out.println(a.isEmpty());//判断是否为空集合
// a.remove("c");//在集合中指定删除某一个元素
// System.out.println( a.remove("c"));//成功为ture,失败为false
// System.out.println( a.retainAll(b));//保留取交集,成功为ture,失败为false
// System.out.println(a.size());//输出该集合的长度 //数组length是为属性,字符串length()为方法,集合size()为方法
// String [] sobject=a.toArray(new String [a.size()]);//将集合转化为指定类型
// System.out.println(Arrays.toString(sobject));
// Object [] b1=a.toArray();//转化成Object类型
System.out.println(a);
System.out.println(b);
LinkedList的常用方法
- add(int index,Object element)
- addFirist(Object element)
- addLast(Object element)
- get(int index)
- removeFirst()
- removeLast()
- remove(int index)
- getFirst()
ArrayList<String> s=new ArrayList<>();
s.add("a");
s.add("b");
s.add("c");
s.add("d");
System.out.println(s.get(2));//根据索引得到指定位置的元素
s.remove(0);//删除并返回指定位置的元素
System.out.println(s);
s.set(0,"X");//替换指定元素并返回数组
System.out.println(s);
s.size();
System.out.println(s.size());//返回实际元素个数
s.addFirst("X");
s.addLast("X");
System.out.println(s.get(2));
System.out.println(s);
List
接口集合迭代
- for循环遍历
- 增强for循环的遍历
- 迭代器遍历(Iterator)
想必for循环和增强for循环大家已经熟练的掌握了,现在给大家演示一下迭代器循环:
迭代器遍历集合1:返回了一个ArrayList的内部类对象,实现Iterator接口
// 此类部类,专门用作对集合进行遍历时的控制
// ArrayList<String> llist=new ArrayList();
// llist.add("a");
// llist.add("b");
// llist.add("c");
// llist.add("d");
// llist.add("e");
// llist.add("f");
// llist.add("g");
// llist.add("g");
// Iterator<String> it=llist.iterator();
// while(it.hasNext()){//判断集合中是否有元素
// String e=it.next();//将下一个元素赋给e
// if(e.equals("g")){
// it.remove();//删除时用迭代器进行方法调用,底部有自动的计数器
// }
// }System.out.println(llist);
//迭代器集合2,提供ListIterator()方法
LinkedList<String> llist = new LinkedList();
llist.add("a");
llist.add("b");
llist.add("c");
llist.add("d");
llist.add("e");
llist.add("f");
llist.add("g");
llist.add("g");
ListIterator<String> it = llist.listIterator(llist.size());//此方法可以指定位置进行迭代
// while(it.hasNext()){
// String e=it.next();
// System.out.println(e);
// }
while (it.hasPrevious()) {//此方法可以将集合中的元素进行逆序遍历
String e = it.previous();
System.out.println(e);
}
}
Set 接口
Set接口继承了Collection接口。 Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的。
Set接口有两个实现类
●
HashSet
HashSet类中的元素不能重复,即彼此调用equals方法比较,都返回false。
底层数据结构是哈希表+链表。
哈希表依赖于哈希值存储
●
TreeSet
可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。
TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)。
注意:
Set接口为什么不可以存储重复的元素,它的判断方法是什么呢?
一般的比较对象的方法都是用的hashcode()、equals();在没有被重写之前(Object类),hashcode()比较的是对象在内存中的地址,但是被重写之后,hashcode()比的是该对象的哈希值,在没有被重写之前(Object类),equals()也比较的是对象在内存中的地址,但是在重写之后,equals()比较的是对象的内容是否相等,在Set接口中,它首先比的是对象的哈希值,如果哈希值相同的话(比直接比equals()节约时间),在进一步比较对象的内容相同。
//set共同点:不可重复,无序(不是按照添加的顺序进行排序,杂乱),无序且不重复的集合
//有遍历俩种形式:1.增强for循环 2.迭代器迭代(无索引故不能使用for循环)
// Hashset:存储的元素不固定
// HashSet<String> hset=new HashSet<>();
// hset.add("a");
// hset.add("d");
// hset.add("b");
// hset.add("x");
// hset.add("l");
// hset.add("l");
// hset.add("l");
// System.out.println(hset);
//Treeset:可以按照元素的自然顺序进行排序,有序(根据元素的自然顺序进行排序)且不能存储重复元素
// TreeSet<String> hset=new TreeSet<>();
// hset.add("a");
// hset.add("d");
// hset.add("b");
// hset.add("x");
// hset.add("l");
// System.out.println(hset);
//可以把另外一个集合的元素赋给Treeset。前提是该集合必须和Comparable有关系或者是继承
// Demo3 demo1=new Demo3(1,"baoma");
// Demo3 demo2=new Demo3(2,"baoma");
// Demo3 demo3=new Demo3(3,"baoma");
// TreeSet<Demo3> a=new TreeSet<>();
// a.add(demo1);
// a.add(demo3);
// a.add(demo2);
// System.out.println(a);
Map 接口
l
Map
接口概述 :将键映射到值的对象 ,一个映射不能包含重复的键 ,每个键最多只能映射到一个值
Map接口常用方法
- V put(K key,V value)
- V remove(Object key)
- void clear()
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- boolean isEmpty()
- int size()
- V get(Object key)
- Collection<V> values()
- Set<K> keySet()
-
Set<Map.Entry<K,V>> entrySet()
Map 接口
●
HashMap
- HashMap中元素的key值不能重复,
- 排列顺序是不固定的,可以存储一个为null的键。
●
TreeMap
- TreeMap中所有的元素都保持着某种固定的顺序,如果需要得到一个有序 的Map就应该使用TreeMap,key值所在类必须实现Comparable接口。
●
HashTable
- 实现了同步。
- 不能存储为null的键
Map集合遍历
方式1:
- 根据键找值
- 获取所有键的集合
- 遍历键的集合,获取到每一个键
- 根据键找值
方式2:
- 根据键值对对象找键和值
- 获取所有键值对对象的集合
- 遍历键值对对象的集合,获取到每一个键值对对象
- 根据键值对对象找键和值
map遍历的俩种方法
// HashMap<String,String> a=new HashMap();
// a.put("a","aa");
// a.put("b","bb");
// a.put("c","cc");
// System.out.println(a);
// for (String key:a.keySet()) {
// System.out.println("key:"+key+"value:"+a.get(key));
// }
HashMap<String,String> a=new HashMap();
a.put("a","aa");
a.put("b","bb");
a.put("c","cc");
for (Map.Entry<String,String> c:a.entrySet()) {
System.out.println("key:"+c.getKey()+"value:"+c.getValue());
}
}
● TreeMap
- 适用于按自然顺序或自定义顺序遍历键(key)。
- TreeMap根据key值排序,key值需要实现Comparable接口,重写compareTo方法。TreeMap根据compareTo的逻辑,对key进行排序。
- 键是红黑树结构,可以保证键的排序和唯一性
注意:
HashMap结构:键值对,键不可以重复,值可以重复,可以存储一个null值
底层存储结构:java8
数据结构:1.数组(哈希值)
2.链表
3.红黑树
添加元素过程:根据元素算出它的哈希值,经过计算,算出该元素在数组中的位置,然后将元素封装到Node对象中,将封装好的Node对象存储到对应的位置,然后再有元素存储进来,如果有相同的位置,将新的元素存到相同位置元素的下一位,当链表的长度达到一定长度时,会转化为红黑树
哈希数组的默认长度为16
负载因子为0.75
哈希数组扩容都是原来数组长度的2倍
当链表长度为8,且哈希数组的长度大于等于64时,链表就会转为红黑树
Collections类
● Collections
是集合类的工具类,与数组的工具类
Arrays
类似
.
- addAl l(Col lection<? super T> c, T... elements);
- binarySearch(List<? extends Comparable<? super T>> l ist, T key)
- sort(List<T> l ist)
- sort(List<T> l ist, Comparator<? super T> c)
- swap(List<?> l ist, int i, int j)
- copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于src.size
- emptyList() 返回为空的集合,不能添加数据
- fi l l(List<? super T> l ist, T obj)
- max(Col lection<? extends T> col l)
- min(Col lection<? extends T> col l)
- replaceAl l(List<T> l ist, T oldVal, T newVal)
- reverse(List<?> l ist)
- shuffle(List<?> l ist) 随机排序
- copy(dest,src)集合复制
ArrayList<Integer> list=new ArrayList<>();
list.add(1);
list.add(5);
list.add(3);
list.add(6);
list.add(2);
list.add(4);
// Collections.addAll(list,6,9,8);//int...a 添加若干个元素
Collections.sort(list);
// System.out.println(Collections.binarySearch(list,2));//查找元素的索引
// ArrayList<Integer> list1=new ArrayList<>();
// list1.add(0);
// list1.add(0);
// list1.add(0);
// list1.add(0);
// list1.add(0);
// list1.add(0);
// list1.add(0);
// Collections.copy(list1,list);//复制,list1的size必须比list的size长
// System.out.println(list1);
// Collections.swap(list,1,3);
// Collections.fill(list,1);
// List<Integer> list1 =Collections.emptyList();
// System.out.println(list1);
// System.out.println(Collections.max(list));
// System.out.println(Collections.min(list));
System.out.println(list);