一.
算法介绍(栈、队列、数组、链表、Hash、树)
栈:先进后出,画图存储元素(A,B,C)(压栈),并取出(弹栈)
队列:先进先出,横向队列,存入取出
数组:查询快,增删慢
链表:通过一个链子把多个结点(元素)连接起来,由数据和地址组成的一个元素,
节点本身必须有一个地址值(就是下一个元素的地址值)
特点:查询慢,增删快
分为:单向链表:数据+下一个元素的地址
双向链表 :数据+下一个元素的地址+上一个元素的地址
单向循环链表 :最后一个元素存储的地址是第一个元素的地址值
双向循环链表:存储的是两个地址,最后一个元素所存储的两个地址分别是上一个元素的地址和第一个元素的地址
二.集合概念
2
* 为什么出现集合类?
* 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,我们就需要对这多个对象进行存储。
* 而目前为止我们学习过的可以存储多个元素的东西是数组,但是呢,数组长度固定,不能适应变化的需求,所以,Java
* 就提供了集合类供我们使用。
三
* Java提供了集合类供我们使用,而我们的需求可能是这样的:
* 我要求我的元素是有序的,
* 我要求我的元素是无序的,
* 我要求我的元素是唯一的,
* 我要求我的元素是可以重复的。
* 为了满足不同的需求,Java就提供了不同的集合类。
* 而这些集合类由于数据结构不同,才可以满足这些条件的。
* 数据结构:存储元素的方式。
* 而无论这些集合的结构是什么样子的,都是要装水的,所以,他们应该有共性的内容。
* 通过不断的向上提取,最终会形成一个集合的继承体系图。
五.开发中常类介绍
集合部分:
1.Collection
1.1
简单介绍这个接口
是集合的顶层结构,定义了集合的共性功能。
可以存储对象,这些对象也被称为元素。
1.2(学习方法)
* 成员方法:(看到E我们先把它理解为Object即可)
* A:添加功能
* boolean add(Object obj):往集合中添加一个元素
* boolean addAll(Collection c):往集合中添加多个元素
* B:删除功能
* void clear():清空所有元素
* boolean remove(Object o):从集合中删除一个元素
* boolean removeAll(Collection c):从集合中删除另一个集合的元素
* C:判断功能
* boolean contains(Object o):判断集合中是否包含指定的元素
* boolean containsAll(Collection c):判断集合中是否包含另一个集合的元素
* boolean isEmpty():判断集合是否为空。
D:交集功能
* boolean retainAll(Collection c)
* E:迭代器(集合特有的遍历方式)
* Iterator iterator()
重点:Iterator的使用
A:使用步骤
B:迭代器原理
* F:长度功能
* int size():返回集合中元素的个数
*
* 迭代器是依赖于集合而存在的。所以,要想得到迭代器对象,必须先有集合对象。
* 迭代步骤:
* A:通过集合对象获取到迭代器对象
* B:通过迭代器对象的hasNext()方法判断是否有元素
* C:通过迭代器对象的next()方法获取元素
1.5
练习:创建狗对象(带参数),存储到集合,用迭代器进行遍历并打印对象的属性数据
package com.edu05;
public class Dog {
private String Name;
private int age;
public Dog(String name, int age) {
super();
Name = name;
this.age = age;
}
public Dog() {
super();
// TODO Auto-generated constructor stub
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.edu05;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class DogTest {
public static void main(String[] args) {
//创建狗对象
Dog d1 = new Dog("刘阿狗",22);
Dog d2 = new Dog("bob",2);
Dog d3 = new Dog("小黄",3);
//创建集合
Collection<Dog>c=new ArrayList<Dog>();
//将Dog对象添加到集合
c.add(d1);
c.add(d2);
c.add(d3);
//迭代器遍历
Iterator<Dog> it = c.iterator();
while (it.hasNext()) {
Dog d=it.next();
System.out.println(d.getName()+" "+d.getAge());
}
}
}
2.List
(1)List集合的元素有序(存储和取出顺序一致),元素可重复
(2)List的特有功能:
A:添加功能
void add(int index,Object obj):在指定的位置添加元素
B:删除功能
Object remove(int index):通过指定的索引删除元素,并把删除的元素返回
C:获取功能
get(int index) 返回列表中指定位置的元素。
D:替换功能
Object set(int index,Object obj)
(3)案例:
A:List存储字符串并遍历(迭代器,普通for)
B:List存储自定义对象并遍历(迭代器,普通for)
(4).List的倒序与洗牌
List中元素顺序可以被洗牌Collections.shuffle(list)
List中元素顺序可以被倒序Collections.reverse(list)
Collections.sort(list)对List元素排序(字母数字分别进行测试)
案例练习:
* 需求:用List集合存储3个汽车对象,然后遍历。
*
* 汽车:Car
* 成员变量:String brand,int price,String color
* 构造方法:无参,带参
* 成员方法:getXxx()/setXxx()
*
* 注意事项:
* A:忘写main方法。
* B:导入包的问题,集合操作的时候,导入包基本上都是在java.util下
* C:大家针对我们的命名规范有些忘记了,需要回来再看一下
* 类,接口等名称是首字母大写
* 变量或者方法名首字母小写
package com.edu09;
public class Car {
private String brand;
private int price;
public Car(String brand, int price) {
super();
this.brand = brand;
this.price = price;
}
public Car() {
super();
// TODO Auto-generated constructor stub
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
package com.edu09;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//获取汽车对象
Car c1 = new Car("兰博基尼",1000);
Car c2 = new Car("劳斯莱斯",3000);
Car c3 = new Car("奥迪",4000);
//创建集合
List<Car>l=new ArrayList<Car>();
//把汽车对象存储到集合
l.add(c1);
l.add(c2);
l.add(c3);
//迭代器遍历
Iterator<Car> it = l.iterator();
while (it.hasNext()) {
Car c=it.next();
System.out.println(c.getBrand()+" "+c.getPrice());
}
System.out.println("-----------------------");
//普通for循环遍历
for (int j = 0; j < l.size(); j++) {
Car c=l.get(j);
System.out.println(c.getBrand()+" "+c.getPrice());
}
System.out.println("-----------------------");
//增强for循环遍历
for (Car c : l) {
System.out.println(c.getBrand()+" "+c.getPrice());
}
}
}
*ArrayList与LinkedList的相同点与不同点 (面试题**)
相同点:有顺序的,元素可以重复
(1)ArrayList特点:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
(2)LinkedList特点:
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
*List的遍历(掌握)
1.for(普通for)
2.Iterator(迭代器)
3.foreach(增强for)
*泛型入门
泛型(掌握)
(1)是一种把明确数据类型的工作推迟到创建对象或者调用方法的时候才去明确类型的特殊类型
(2)格式:
<数据类型>
默认情况下,是Object类型。
这里数据类型只能是引用类型。如果你看到写基本类型也行,其实这里使用了自动装箱。
(3)好处:
A:把运行时期问题提前到了编译时期
B:避免了强制类型转换
C:优化程序设计,解决了黄色警告线问题
(4)在哪里用?
一般来说就是在集合中用的多。
看API,如果类或者接口或者方法出现了<>说明这里就有泛型。
拓展(有时间的话可以讲一讲,听懂了解就可以):
(5)泛型的概述(了解)
A:泛型类(把泛型定义在类上)
B:泛型方法(把泛型定义在方法上)
C:泛型接口(泛型定义在接口上)
(6)泛型通配符(先不进行讲解,后面会根据实例一一进行讲解)
<?> 不确定类型
<? extends E> 向上限定,E及其子类
<? super E> 向下限定,E及及其父类
集合
1.Set
1.1常用方法:直接查看api,里面的方法我们基本都是学过的哦
2.HashSet(查询api看说明进行讲解)
2.1 元素顺序:元素唯一,但是无序(它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变)
案例:创建一个HashSet集合,添加元素(String元素),测试唯一性,无序性
package com.edu_01;
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args) {
//创建一个HashSet集合
HashSet<String> set = new HashSet<String>();
//给集合中添加元素
set.add("hello");
set.add("java");
set.add("world");
set.add("c++");
set.add("php");
set.add("hello");
//遍历集合
/**
* HashSet集合特点:
* 1.元素无序
* 2.元素唯一
*/
for (String string : set) {
System.out.println(string);
}
}
}
2.2如何保证元素的唯一性的呢(分析源码)?
* 通过简单的分析,我们知道HashSet集合保证元素的唯一性和add()方法相关。
* 如何我们想深入的了解,就必须看add()方法的源码,看它的底层依赖什么内容?
* if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {...}
*
* 左边:e.hash == hash
* 比较对象的哈希值。
*
* 右边:((k = e.key) == key || key.equals(k))
* 左边:(k = e.key) == key
* 比较对象的地址值。
*
* 右边:key.equals(k)
* 比较的是对象的内容是否相同。默认情况下比较的是地址值
结论:
底层数据结构是哈希表。
哈希表依赖两个方法:hashCode()和equals()
执行流程:
首先判断哈希值是否相同,如果不同,就直接添加到集合。
如果相同,继续执行equals(),看其返回值,
如果是false,就直接添加到集合。
如果是true,说明元素重复不添加。
使用:
如果你看到哈希结构的集合,就要考虑可能需要重写这两个方法。
如果真要重写,自动生成即可。
知识点demo演练:
1.存储String类型的元素,说明元素无序且唯一
2.分析add()方法,保证唯一性的原理(底层依赖于hashCode()和equals()方法,保证了元素的唯一性)
3.存储自定义对象,如何保证元素的唯一性?(存储相同元素,发现无法保证元素的唯一性)
3.TreeSet(查看api,得出结论)
3.1 元素顺序:使用元素的自然顺序对元素进行排序,或者根据创建 set时提供的 Comparator进行排序(比较器排序),
具体取决于使用的构造方法。
3.2 底层算法:二叉树(画图进行讲解)
3.3 元素要求, 加入自定义JavaBean
案例演练:
1.创建集合存储Integer类型的元素(20,18,23,22,17,24,19,18,24),分析如何保证元素唯一性,以及排序的规则。二叉树
(首先讲解二叉树数据结构是怎么存入元素的,根据compareTo()方法的返回值来确定要存入元素的安放位置)
2.存储字符串并遍历(字母a-z排序)
3.存入学生对象(姓名,年龄),1.按年龄排序,2.姓名排序(自然排序实现Comparable接口,并重写comparaTo()方法)
4.创建set集合的时候,传入Comparator(比较器排序)进行排序,进行排序(比较器排序)
4.Set的遍历
4.1Iterator:
4.2foreach:
5.HashSet与TreeSet的相同点与不同点
相同点:
单列集合,元素不可重复
不同点
1. 底层存储的数据结构不同
HashSet底层用的是HashMap哈希表结构存储,而TreeSet底层用的是TreeMap树结构存储
2.存储时保证数据唯一性依据不同
HashSet是通过复写hashCode()方法和equals()方法来保证的,而TreeSet通过Compareable接口的compareTo()方法来保证的
3.有序性不一样
HashSet无序,TreeSet有序
* 这种情况的数据,属于一一对应的映射关系。这种关系的集合在java叫Map。
* Map:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
* Map接口中的方法概述(创建集合测试方法):
* A:删除功能
* void clear():移除集合中的所有键值对元素
* V remove(Object key):根据键移除键值对元素,并返回值
* B:判断功能
* boolean containsKey(Object key):判断集合中是否包含指定的键
* boolean containsValue(Object value):判断集合中是否包含指定的值
* boolean isEmpty():判断集合是否为空
* C:获取功能
* Set<Map.Entry<K,V>> entrySet():获取键值对对象的集合,遍历键值对对象,
利用getKey(),getValue()取出键和值(理解即可)
*
V get(Object key):根据键获取值
* Set<K> keySet():获取所有的键
* Collection<V> values():获取所有的值
* D:添加功能
* V put(K key,V value):集合添加键值对
* E:长度功能
* int size():键值对对数。
2.HashMap
2.1元素顺序:元素顺序不可预测
2.2底层算法:哈希算法
2.3对键没有要求(仅仅相对于TreeMap来说)
知识点demo演练:
1.存入(String,String)主要讲解遍历方式,键:丈夫 值:妻子
2.存入(String,Student)键:String(国籍) 值:Student
3.存入(Student,String),键是同一个对象的时候要把之前存入的元素挤出去,想要实现这样的效果的话,
需要重写javabean里面的hashCode()和equals()方法
package com.edu_08;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
/**
* 2.HashMap
2.1元素顺序:元素顺序不可预测
2.2底层算法:哈希算法
2.3对键没有要求(仅仅相对于TreeMap来说)
*/
public class HashMapDemo {
public static void main(String[] args) {
// 1.存入(String,String)主要讲解遍历方式,键:丈夫 值:妻子
HashMap<String, String> hm = new HashMap<String,String>();
//给键值对集合存入元素
hm.put("文章", "马伊琍");
hm.put("黄晓明", "baby");
hm.put("汪老师", "章子怡");
hm.put("周杰伦", "昆凌");
//hm.put("文章", "姚笛");,当后面存入的元素和前面的键的值相同的时候,前面的元素的值会被后面的元素的值代替
//遍历,通过建找值
Set<String> keys = hm.keySet();
for (String key : keys) {
System.out.println(key+" "+hm.get(key));
}
System.out.println("-------------");
//通过找到结婚证,来分别找到丈夫和妻子
Set<Entry<String,String>> entrySet = hm.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}