面向对象
3.4、数据结构
常见的数据结构
数据存储的常用结构有:栈、队列、数组、链表和红黑树。
栈:先进后出
队列:先进先出
数组:查询快,增删慢
链表:
查询慢: 链表中地址不是连牍的,每次查询元素都必须从头开始查询
增删快: 链表结构,增加/删除一个元素对链表的整体结构没有影响所以增删快
- 链表中的每一个元素也称之为一个节点
- —个节点包含了一个数据源(存储数据,两个指计域(存储地址)
单向链表:链表中只有一条链子.不能保证元素的顺序(存储元素和取出元素的顺序有可能不一致)
双向链表:链表中有两条链子,有一条链子是专门记录元素的顺度是一个有序的集合
红黑树:查询非常快
3.5、List集合
List接口的特点:
-
有序的集合,存储元素和取出元素的顺序是一致的(存储123取出123)
-
有索引包含了一些带索引的方法
-
允许存储重复的元素
List接口中带索引的方法(特有):
-
public void add(int index, E eLement): 将指定的元素,添加到该集合中的指定位置上。
-
public E get(int index): 返回集合中指定位置的元素。
-
public E remove(int index): 移除列表中指定位置的元素,返回的是被移除的元素。
-
public E set(int index,E element): 用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
注意:操作索引的时候,一定要防止索引越界异常
public class DemoList {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println(list);//[a, b, c, d]
list.add(3,"赤兔"); //将指定的元素,添加到该集合中的指定位置上。
System.out.println(list); //[a, b, c, 赤兔, d]
String k = list.remove(2); //移除列表中指定位置的元素,返回的是被移除的元素。
System.out.println("被移除的是:"+k); //被移除的是:c
System.out.println(list); //[a, b, 赤兔, d]
String m = list.set(1, "吕布"); //用指定元素替换集合中指定位置的元素
System.out.println("被替换的是:"+m); //被替换的是:b
System.out.println(list); //[a, 吕布, 赤兔, d]
for (int i = 0; i < list.size(); i++) {//普通for循环遍历
String s = list.get(i); //返回集合中指定位置的元素
System.out.println(s);
}
Iterator<String> it = list.iterator(); //迭代器遍历
while (it.hasNext()){
String g = it.next();
System.out.println(g);
}
for (String y : list){ //增强for循环
System.out.println(y);
}
}
}
3.6、LinkedList集合
LinkedList集合的特点:
-
底层是一个链表结构:查询慢,增删快
-
里边包含了大量操作首尾元素的方法
注意:使用LinkedList集合特有的方法,不能使用多态
-
public void addFirst(E e): 将指定元素插入此列表的开头。
-
public void addLast(E e): 将指定元素添加到此列表的结尾。
-
public void push(E e): 将元素推入此列表所表示的堆栈。
-
public E getFirst(): 返回此列表的第一个元素。
-
public E getlast(): 返回此列表的最后一个元素。
-
public E removeFirst(): 移除并返回此列表的第一个元素。
-
public E removeLast(): 移除并返回此列表的最后一个元素。
-
public E pop(): 从此列表所表示的堆栈处弹出一个元素。
-
public boolean isEmpty(): 如果列表不包含元素,则返回true。
3.7、HashSet集合
set接口的特点:
-
不允许存储重复的元素
-
没有索引,没有带索引的方法,也不能使用普通的for循环遍历
Hashset特点:
-
不允许存储重复的元素
-
没有索引,没有带索引的方法,也不能使用普通的for循环遍历
-
是一个无序的集合,存储元素和取出元素的顺序有可能不一致
-
底层是一个哈希表结构(查询的速度非常的快)
public class DemoSet {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("1");
set.add("2");
set.add("3");
set.add("1");
Iterator<String> it = set.iterator();
while (it.hasNext()){ //使用迭代器进行遍历
String s = it.next();
System.out.println(s);//1,2,3
}
for (String b : set){ //增强for
System.out.println(b);//1,2,3
}
}
}
哈希值
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)
- int hashcode()返回该对象的哈希码值。
哈希表
Set集合存储元素不重复的原理
Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复
Hashset存储自定义类型元素
set集合报错元素唯一:
- 存储的元素(String,Integer, . . .Student ,Person. . . ) ,必须重写hashcode方法和equals方法
LinkedHashSet集合
linkedHashset集合特点:
- 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序
- 有序,不允许重复
3.8、可变参数
可变参数: 是JDK1.5之后出现的新特性
使用前提:
- 当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数.
使用格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型...变量名){}
可变参数的原理:
- 可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数传递的参数个数,可以是o个(不传递),1,2...多个
public class DemoAdd {
public static void main(String[] args) {
System.out.println(add(10,20,30));
}
public static int add(int...arr){
int sum = 0;
for (int i : arr) {
sum += i;
}
return sum;
}
}
可变参数的注意事项
-
—个方法的参数列表,只能有一个可变参数
-
如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
3.9、collections集合工具类
-
public static boolean addAll(Collection c,T... elements) : 往集合中添加一些元素。
-
public static void shuffle(list<?> list)打乱顺序:打乱集合顺序。
public class DemoCollections {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"a","b","c","d","e");//一下就存入
System.out.println(list);//[a, b, c, d, e]
Collections.shuffle(list);//打乱顺序
System.out.println(list);//[b, e, d, c, a]
}
}
-
public static void sort (list list): 将集合中元素按照默认规则排序。
-
public static void sort(List list, Comparator<? super T>): 将集合中元素按照指定规则排序。
- Comparator和comparable的区别
- Comparable:自己(this )和别人(参数)比较,自己需要实现Comparable接口,重写比较的规则compareTo方法
- comparator:相当于找—个第三方的裁判,比较两个
- Comparator和comparable的区别
public class DemoSort {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(5);
list.add(2);
System.out.println(list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;//升序 o2-o1为降序
}
});
System.out.println(list);
}
}
4.0、Map集合
Map集合的特点:
-
Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
-
Map集合中的元素, key和value的数据类型可以相向,也可以不同
-
Map集合中的元素,key是不允许重复的, vatue是可以重复的
-
Map集合中的元素,key和value是——对应
Map常用子类
HashMap集合的特点:
-
HashMap集合底层是哈希表:查询的速度特别的快
- JDK1.8之前:数组+单向链表
- JDK1.8之后:数组+单向链表/红黑树(链表的长度超过8): 提高查询的速度
-
hashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致
linkedHashMap的特点:
-
LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)
-
LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的
Map常用方法
-
public v put(K key,v value): 把指定的键与指定的值添加到Map集合中。
-
public v remove(0bject key): 把指定的键所对应的键值对元素在Map集合中删除,返回被删除元素的值。
-
public v get(0bject key) :根据指定的键,在Map集合中获取对应的值。
-
boolean containsKey(0bject key) :判断集合中是否包含指定的键。
-
public Set keySet(): 获取Map集合中所有的键,存储到Set集合中。
-
public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
Map遍历
Map集合的第一种遍历方式:通过键找值的方式
实现步骤:
1、使用Map集合中的方法keySet(),把Map集合所有的key取出来,存储到一个Set集合中
2、遍历set集合,获取Map集合中的每一个key
3、通过Map集含中的方法get ( key),通过key找到value
public class DemoMap {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("张无忌",18);
map.put("谢逊",20);
map.put("张三丰",18);
Set<String> set = map.keySet();//把键存到set集合中
Iterator<String> it = set.iterator();//迭代器
while (it.hasNext()){
String key = it.next();
Integer integer = map.get(key);//获取键对应的值
System.out.println(key+"="+integer);
}
// for (String key : set){ 增强for
// Integer value = map.get(key);
// System.out.println(key+"="+value);
// }
}
}
Map集合遍历的第二种方式:使用Entry对象遍历
实现步骤:
1、使用Map集合中的方法entrySet() ,把Map集合中多个Entry对象取出来,存储到一个set集合中
2、遍历set集合,获取每一个Entry对象
3、使用Entry对象中的方法getKey ()和getValue( )获取键与值
public class DemoMap01 {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("内瑟斯",20);
map.put("凯尔",21);
map.put("卡尔萨斯",22);
Set<Map.Entry<String, Integer>> set = map.entrySet();//把Map集合中多个Entry对象取出来,存储到一个set集合中
Iterator<Map.Entry<String, Integer>> it = set.iterator();
while (it.hasNext()){
Map.Entry<String, Integer> entry = it.next();
String key = entry.getKey(); //使用Entry对象中的方法getKey()和getValue()获取键与值
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
}
}
Hashtable集合
Hashtable ;底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速展慢
HashMap:底层是一个哈希表,是一个线程不安全的集合,是多线程的集合,速度快
HashMap集合(之前学的所有的集合):可以存储nulL值, nulL键
Hashtable集合,不能存储null值, null键
Hashtable和vector集合一祥,在jdk1 .2版本之后被更先进的集合(HashMap, ArrayList )取代了
hashtable的子类Properties依然活跃在历史舞台