首先我们给一个框架图:(本人认为:集合和映射实际上就是方法的使用,多学习API即可)
框架图
?接着我们一个一个来盘
1.Collection集合:存放的是单一的值 ?* 存储不唯一的 无序的对象 ?* 特点: ?* 1、可以存放不同类型的数据,而数组只能存放固定类型的数据 ?* 2、当使用arraylist子类实现的时候,初始化的长度是10,当长度不够用的时候就会自动扩容 ?* 看源码grow();可知会自动>>1位,也就是扩容1.5倍 ?* API方法: ?*?? 增加数据的方法 ?*???????????? add:要求必须传入的参数是Object对象,因此当写入基本数据类型的时候,包含了自动拆箱和自动装箱的过程 ?*???????????? addAll:添加另一个集合的元素到此集合中 ?* ?*???????????? 删除数据的方法 ?*???????????? clear:只是清空集合中的元素,但是此集合对象并没有被回收 ?*???????????? remove:删除指定元素 ?*???????????? removeAll:删除集合元素 ?*???????????? 查询数据的方法 ?*???????????? contains:判断集合中是否包含指定的元素值 ?*???????????? containsAll:判断此集合中是否包含另一个集合 ?*???????????? isEmpty:判断集合是否等于空 ?*???????????? retainAll:若集合中拥有另一个集合的所有元素,返回true,否则返回false ?*??????????? size:返回当前集合的大小 ?* ?*???????????? //集合转数组的操作 ?*??????????? toArray:将集合转换成数组
public class CollectionDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("abc");
c.add(123);
c.add(true);
c.add(123);
// c.remove(123);
// c.clear();
System.out.println(c.contains(123));
Collection c1 = new ArrayList();
c1.add("bcd");
c1.add("def");
c1.add(456);
// System.out.println(c1.addAll(c));
System.out.println(c1);
System.out.println(c);
// c1.removeAll(c1);
// System.out.println(c1);
System.out.println(c.isEmpty());
// System.out.println(c.retainAll(c1));
System.out.println(c.size());
Object[] objects = c.toArray();
for (int i = 0; i <objects.length ; i++) {
System.out.println(objects[i]);
}
}
}
?2.List:存放的是单一的值 存储一组 不唯一 有序的对象
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc");
list.add(123);
list.add(true);
list.add(123);
list.add(15.0);
list.add(1,"OK");
System.out.println(list);
System.out.println(list.get(0));
System.out.println(list.size());
System.out.println(list.lastIndexOf(123));
System.out.println(list.indexOf(123));
System.out.println(list.set(4,"Oyear"));
System.out.println(list);
/*跟subString一样都是截取,截头不结尾
只是subString是截取字符串,subList是截取索引出处的值
*/
System.out.println(list.subList(0,4));
}
}
3.
ArrayList ?? ?初始容量是10 底层是由数组实现,但它实现了长度可变的数组(可以进行扩容 一次扩容1.5倍) 优点:遍历元素和随机访问元素的效率比较高 缺点:添加和删除需要移动大量的元素,效率低
?? ? 1.ArrayList是非线程安全的,高效率, 2.Vector是线程安全的,低效率 ?ArrayList扩容是每次扩容1.5倍,Vector扩容是每次扩容2倍
4.LinkedList实现类 ?? ?采用的是链表存储方式 优点:插入删除元素的效率比较高 缺点:遍历和随机访问元素的效率低下
package com.shun.changyong;
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("abc");
linkedList.add(123);
linkedList.add(true);
linkedList.add(18.0);
//在指定位置插入元素
linkedList.add(0,"Java!");
LinkedList linkedList1 = new LinkedList();
//丛指定集合插入第一个元素的索引(如果索引输入为1则会出现数组越界异常)
// linkedList1.addAll(0,linkedList);
linkedList1.addAll(linkedList);
//在列表开头、结尾插入元素
linkedList.addFirst("加油");
linkedList.addLast("努力");
//删除集合中所有元素
// linkedList.clear();
//判断集合中有没有指定元素 有就true 没有就 false
System.out.println(linkedList.contains("123"));
//检索头不删
System.out.println(linkedList.element());
System.out.println(linkedList.peek());
//检索头并删除
System.out.println(linkedList.poll());
System.out.println(linkedList.remove());
//返回指定的元素
// System.out.println(linkedList.get(5));
//从堆栈中弹出列表头 并从列表中删除
System.out.println(linkedList.pop());
//替换指定索引出元素
System.out.println(linkedList.set(3,"傻逼java!"));
// System.out.println(linkedList1);
System.out.println(linkedList);
//转换为数组并进行输出
Object[] objects = linkedList.toArray();
for (int i = 0; i <linkedList.size() ; i++) {
System.out.println(objects[i]);
}
System.out.println(linkedList.size());
}
}
5.Set接口 ?? ?* Set接口: ?* 1.无序的 唯一的(不可重复的) ?* 2.使用TreeSet底层的实现是TreeMap,利用红黑数原理实现,也就是数据传入的数据类型要一致 ?* 3.设置元素的时候,如果是自定义的对象,会查找对象中的toString方法和hashCode方法,如果没有比较的是地址 ?* 4.树中的元素是默认会进行排序操作的,如果是基本数据类型,自动比较,如果是引用数据类型,要自定义比较器 ?* 比较器分类: ?*? 内部比较器: ?*????????? 1.实现Comparable接口 ?*????????? 2.定义在元素类中 ?*? 外部比较器: ?*????????? 1.定义在当前类中 ?*????????? 2.实现Comparator接口,但是要将该比较器传递到集合中(作为参数传入) ?*????????? 注意: ?*????????? 1.当内部比较器和外部比较器同时存在时,执行的是外部比较器 ?*????????? 2.外部比较器可以定义成一个工具类,可以复用,而内部比较器只有在存储当前对象的时候可以使用 ?*????????? 3.当使用比较器的时候,不会调用equals方法
public class SetDemo {
public static void main(String[] args) {
Set set = new HashSet();
set.add(123);
set.add("abc");
set.add(true);
set.add(100L);
//如果集合中不包含元素就返回true
System.out.println(set.isEmpty());
//删除所有元素
// set.clear();
System.out.println(set);
//迭代器遍历数组
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("===============================");
//增强for循环
for(Object o : set ){
System.out.println(o);
}
Set set = new TreeSet();
set.add(123);
set.add("abc");
set.add(true);
set.add(100L);
// 传入数据类型一致(自动使用红黑树算法进行了排序)
set.add(123);
set.add(12);
set.add(25);
set.add(16);
set.add("jisj");
set.add("der");
set.add("ios");
set.add("ces");
System.out.println(set);
for (Iterator iterator = set.iterator(); iterator.hasNext();){
System.out.println(iterator.next());
}
}
}
6.Iterator迭代器 ?? ?? 所有的集合类都默认实现了Iterable的接口,实现此接口意味着具备了增强for循环的能力,也就是for-each 一般用来遍历数组使用 1.使用普通for循环 2.使用迭代器遍历,也就是使用iterator中的hasNext();和next()方法; 3.增加for循环 ??????? for(Object o : list){ ??????????? System.out.println(o); ??????? }
package com.shun.changyong;
;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add("abc");
list.add(1234);
list.add(true);
//遍历数组
for (int i = 0; i <list.size() ; i++) {
System.out.println(list.get(i));
}
//使用迭代器遍历数组
System.out.println("++++++++++++++++++++++++++");
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("============================");
//增加for循环
for(Object o : list){
System.out.println(o);
}
}
}
?7.Map映射:<k,v>对,又称键值对 ????????????????通过Key找Value可以找到 ????????????????通过Value找Key不可以 8. ? HashMap和Hashtable的区别: 1.HashMap线程不安全,效率高 2.HashTable线程安全,效率低 3.HashMap中的key和value都可以为空,但是只能允许有一个null值,HashTable都不允许为空 ??? 4.TreeMap, 自行学习API
package com.shun.zuoye;
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("a",1);
map.put("d",2);
map.put("c",3);
map.put("b",5);
map.put("e",4);
// System.out.println(map);
//判断map中有没有k(映射),有就返回true
System.out.println(map.containsKey("a"));
//判断map中有没有v(指定值),有就返回为true
System.out.println(map.containsValue(1));
//判断此映射是否为空,为空就返回true
System.out.println(map.isEmpty());
// System.out.println(map.remove("a"));
// System.out.println(map);
//遍历方式
//取出key键
Set<String> key2 = map.keySet();
for (String key : key2){
System.out.println(key + "=" +map.get(key));
}
System.out.println("******************************************");
Set<String> key1 = map.keySet();
for (Iterator<String> iterator = key1.iterator(); iterator.hasNext();){
String key = iterator.next();
System.out.println(key+ "=" +map.get(key));
}
System.out.println("******************************************");
Collection<Integer> values = map.values();
for (Integer value :values){
System.out.println(value);
}
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
for (Map.Entry<String, Integer> entry : entrySet){
System.out.println(entry.getKey()+ "=" +entry.getValue());
}
}
}
顺便说一下数据结构,现在学的虽然不多,但是也得记录一下
9.数据结构
(1)二叉树 ?? ?1.左节点的子节点要小于根节点,右子节点要比根节点大 2.一个根节点最多有两个子节点
(2)红黑树 ?? ?1.根的节点是黑色 2.每个红色节点的两个子节点是黑色的 3.红黑树牺牲了部分平衡性,以换取 插入\删除 操作时的少量的旋转操作,整体性能要优于AVL数 4.最长的路径不超过最短路径的2倍
(3)AVL平衡树 ?? ?1.一个根节点下面有且只有2个子节点 2.任何子节点的两个子树高度最大差别不超过绝对值1
==========================================================
1.集合中的工具类
工具类 ?? ?Collections类 ?? ??? ?方法为主(查看API) ?? ?Arrays类 ?? ??? ? Arrays工具类(详情查看API) ? Arrays提供了数据操作的工具类,包含很多方法 ??????? 集合和数组之间的转换 ?????? 数组转成list: 1.数组转集合:asList();方法 2.集合转数组:toArray();方法
package com.shun.changyong;
import java.util.*;
/**
* Collections工具类
* 在使用二分查找法的前提是先要对集合中的元素进行排序
*/
public class CollectionsDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(12);
list.add(13);
list.add(15);
list.add(10);
list.add(17);
//将所有指定元素添加到指定集合中
Collections.addAll(list,1,2,5);
System.out.println(list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
if (o1 > o2){
return -1;
}else if (o1 < o2){
return 1;
}else {
return 0;
}
}
});
System.out.println(list);
//二分查找法,使用前需要先进行排序
System.out.println(Collections.binarySearch(list,12));
//用指定元素替换集合中的所有元素
Collections.fill(list,123);
System.out.println(list);
}
}
2.泛型
泛型 ?? ?当做一些集合的统一操作的时候,需要保证集合的类型是统一的,此时需要泛型来进行限制 ?*????? 优点: ?*????????? 1、数据安全 ?*????????? 2、获取数据时效率比较高 ?*????? 给集合中的元素设置相同的类型就是泛型的基本需求 ?*?????? 使用: ?*????????? 在定义对象的时候,通过<>中设置合理的类型来进行实现 ?*? 泛型的高阶应用: ?*????? 1、泛型类 ?*????????? 在定义类的时候在类名的后面添加<E,K,V,A,B>,起到占位的作用,类中的方法的返回值类型和属性的类型都可以使用 ?*????? 2、泛型接口 ?*????????? 在定义接口的时候,在接口的名称后添加<E,K,V,A,B>, ?*????????? 1、子类在进行实现的时候,可以不填写泛型的类型,此时在创建具体的子类对象的时候才决定使用什么类型 ?*????????? 2、子类在实现泛型接口的时候,只在实现父类的接口的时候指定父类的泛型类型即可,此时,测试方法中的泛型类型必须要跟子类保持一致 ?*????? 3、泛型方法 ?*????????? 在定义方法的时候,指定方法的返回值和参数是自定义的占位符,可以是类名中的T,也可以是自定义的Q,只不过在使用Q的时候需要使用< ?*????????? Q>定义在返回值的前面 ?*????? 4、泛型的上限(工作中不用) ?*????????? 如果父类确定了,所有的子类都可以直接使用 ?*????? 5、泛型的下限(工作中不用) ?*????????? 如果子类确定了,子类的所有父类都可以直接传递参数使用 ??
public class FanxingDemo {
public static void main(String[] args) {
//从JDK1.8之后后面这个<String>可以不用写
List<String> list = new ArrayList<String>();
// list.add(1);
// list.add("abc");
// list.add(true);
// list.add(100L);
list.add("123");
list.add("abc");
list.add("true");
list.add("100L");
System.out.println(list);
// //遍历数组
// for (int i = 0; i <list.size() ; i++) {
// System.out.println(list.get(i));
// }
//迭代器
// Iterator iterator = list.iterator();
// while(iterator.hasNext()){
// System.out.println(iterator.next());
// }
// //迭代器
// for (Iterator iterator = list.iterator();iterator.hasNext();){
// System.out.println(iterator.next());
// }
System.out.println("************************");
增强for循环
// for (String s : list){
// System.out.println(s);
// }
//FanxingClass<String> f = new FanxingClass<String>();
//f.setName("小白");
//f.setA("shie");
//f.show();
FanxingClass<Dog> f = new FanxingClass<Dog>();
f.setName("xiaohie");
System.out.println(f.getName());
f.setA(new Dog("花花",15));
System.out.println(f.getA());
f.set(new Dog("妹妹",50));
//泛型方法的使用
FanXingMethod<Dog> f1 =new FanXingMethod<Dog>();
f1.setT(new Dog("小红",15));
f1.show("String");
}
}
泛型类:
package com.shun.changyong;
//<A>就是一个占位符
public class FanxingClass<A>{
private String name;
private A a;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public void show(){
System.out.println(this.a);
System.out.println(this.name);
}
public void set(A a){
System.out.println("这是set中的A"+a);
}
public A get(){
return a;
}
}
泛型方法:
package com.shun.changyong;
//<A>就是一个占位符
public class FanxingClass<A>{
private String name;
private A a;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public void show(){
System.out.println(this.a);
System.out.println(this.name);
}
public void set(A a){
System.out.println("这是set中的A"+a);
}
public A get(){
return a;
}
}
最后在总结一些面试题:方便使用!
1. Vector也是List接口的一个子类实现
?*????? 1、Vector跟ArrayList一样,底层都是使用数组进行实现的
?*????? 2、面试经常问区别:
?*????????? 1) ArrayList是非线程安全的,高效率,Vector是线程安全的,低效率
?*????????? 2) ArrayList扩容是每次扩容1.5倍,Vector扩容是每次扩容2倍
2.StringBuffer和StringBuilder的区别?
(1)StringBuffer是线程安全的低效率,由Synchronized实现
(2)StringBuilder是非线程安全的,高效率
3.HasMap和HasTable的区别?
(1)HasTable是线程安全的,低效率,由synchronize实现
(2)HasMap是非线性安全的,高效率
4.ArrayList和LikedList的区别?
(1)底层数据结构不同,ArrayList底层是基于数组实现的,而LinkedList是链表结构实现
(2)使用场景不同:
Q:ArrayList:
~遍历元素和随机访问效率比较高
~插入和删除的效率比较低
Q:LikedList:
~遍历元素和随机访问效率比较低
~插入和删除的效率比较高
(3)都实现了List接口,但是LikedList接口另有实现了一个Deque接口,可以当队列进行使用
PS:队列:FIFO(先进先出)
|