前言:接下来给大家介绍结合框架,有三个框架,这次讲的是List集合框架
码字不易,关注一下博主吧
思维导图:
目录
1.UML建模
1.集合类图
2.用例图??
2.List集合特点
3.三种遍历方式
4.LinKedList
1.对比ArrayList的数据结构
2.堆栈,队列
5.增长因子论证
6.集合框架ArrayList中的重复元素去重及其底层原理
1.UML建模
由于uml(统一建模语言)在开发中经常会用到,特别是在软件开发中的OOAD阶段,因此要理解和使用uml显得尤为重要?
下载路径:斯塔鲁姆尔 (staruml.io)
进去首页是英语界面不懂的英文的可以用浏览器自带的翻译功能翻译界面,然后点下载
?如果是苹果系统就下载苹果,如果是Windows系统就下载Windows系统
下载完成之后解压资源包,解压路径随意
如果下载了软件不知道怎么操作的可以加好友沟通??
1.集合类图
集合类图的作用:体现集合与集合之间的关系,类与类之间的关系
2.用例图??
用例图的作用:是用户与系统交互的最简单表示形式,展现了用户和与他相关的用例之间的关系?
2.List集合特点
首先给大家普及一下八大基本数据类型
整数: byte,short,int,long
小数:double,float
布尔类型: boolean
字符型: char
String不是八大基本数据类型
?集合本身就是一个容器?
1.增删改查
2.有序
3.可重复
/**
* 集合的基本特点
* 增删改查
* 有序
* 可重复
* @author zjjt
*
*/
public class Dome1 {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("a");//增加
list.add("b");
list.add("c");
list.remove(0);//根据下标删除(下标从0开始的),返回int
list.remove("b");//直接删除对象 ,返回ture或false
list.set(2, "e");//根据下标修改值
System.out.println("现有的集合元素"+list);
}
}
3.三种遍历方式
1.for
2.foreach
3.lterator(迭代器)
*迭代器原理:存在第一个就查出第一个,存在第二个就查第二个以此类推,直到没有下一个为止
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
/**
* for循环
*/
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
/**
* foreach
*/
for (String p : list) {
System.out.println(p);
}
/**
* lterator迭代器
*/
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
4.LinKedList
1.对比ArrayList的数据结构
ArrayList的数据结构是数组,LinKedList的数据结构是节点(链表)
ArrayList查询,修改效率快,增加,删除效率慢
LinKedList增加,删除效率快,查询,修改效率慢
2.堆栈,队列
框架里面的数据是怎么存储的?
1.堆栈式存储(先进后出,假设a,b,c依次进去,那么出来的时候就是c,b,a)
2.队列式存储(先进先出,假设a,b,c依次进去,那么出来的时候就是a,b,c)
*队列是通过LinkedList实现的,队列只能一次取一个
public static void main(String[] args) {
LinkedList<String> list=new LinkedList<String>();
DuiLie dl=new DuiLie(list);
dl.push("a");
dl.push("b");
dl.push("c");
System.out.println(dl.pop());
System.out.println(dl.pop());
System.out.println(dl.pop());
}
}
class DuiLie{
LinkedList<String> li=null;
public DuiLie (LinkedList<String> li) {
this.li = li;
}
//从容器取出元素
public String pop() {
return li.removeFirst();
}
//放元素的方法
public void push(String p) {
li.add(p);
}
?*堆栈反顺序输出,取出时调removeLast()方法
public static void main(String[] args) {
LinkedList<String> list=new LinkedList<String>();
DuiZhan dl=new DuiZhan(list);
dl.push("a");
dl.push("b");
dl.push("c");
System.out.println(dl.pop());
System.out.println(dl.pop());
System.out.println(dl.pop());
}
}
class DuiZhan{
LinkedList<String> li=null;
public DuiZhan (LinkedList<String> li) {
this.li = li;
}
//从容器取出元素
public String pop() {
return li.removeLast();
}
//放元素的方法
public void push(String p) {
li.add(p);
}
5.增长因子论证
*List集合底层是数组结构,它是"可变数组"
*一旦超过默认数组大小,会自动扩容,增长的增长因子为0.5
数组大小不是越大越好,如果数据没那么大就浪费了虚拟机的空间
这里说一下,集合初始化数组大小默认为10(已经过论证)
这里设定默认数组大小为50
public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
ArrayList list=new ArrayList<>(50);
for (int i = 1; i < 101; i++) {
System.out.println(i);
list.add(i);
printElementDataLength(list);
}
}
private static void printElementDataLength(ArrayList list) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field f = list.getClass().getDeclaredField("elementData");
f.setAccessible(true);
Object[] obj = (Object[]) f.get(list);
System.out.println("目前List集合底层存储数据的数组长度:"+obj.length);
}
输出结果为?
?超出设定大小为50的范围的话以0.5增长
6.集合框架ArrayList中的重复元素去重及其底层原理
*如果集合里面没有b就增加b,这里List泛型是<String>,用去重复的方法输出结果为a,b,c
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
//如果集合里面没有b就增加b,这里List泛型是<String>,用去重复的方法输出结果为a,b,c
list.add("a");
list.add("b");
list.add("c");
if(!list.contains("b")) {
list.add("b");
}
System.out.println(list);
}
*这里把List的泛型删了,建一个people类,用同样的方法会多出来一个name为李四sex为18的对象
这是为什么呢 ?
因为每一次创建(new)都开辟了新的内存空间,创建了一个新的对象
明明属性都是一样的,为什么又是一个新的对象呢?
这是因为在java中 ‘list.contains()’ 的确进行了比较,但是比较的不是字符串对象包含的内容,而是他们所在的内存地址的数值。所以会出现字符串包含的内容都是"李四",但是彼此比较的时候却不相等的情况
解决方案:
你只要在people类加上hashCode and equals的方法(这里只用到了equals的方法)就能把重复的内容删除?
*我在hashCode方法与equals方法那里加了被调用时输出方法被调用,下面结果有答案
*List集合是有序的,李四在第二个只判断两次
public static void main(String[] args) {
List list = new ArrayList<>();
//把List的泛型删了,用同样的方法会多出来一个name为李四sex为18的对象
//但是你在people类加上hashCode and equals的方法(这里用到了equals的方法)就把重复的内容删除
list.add(new people("张三", 18));
list.add(new people("李四", 18));//List集合是有序的,李四在第二个只判断两次
list.add(new people("王五", 18));
if(!list.contains(new people("李四", 18))){
list.add(new people("李四", 18));
}
for (Object pp : list) {
System.out.println(pp);
}
}
}
class people {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "people [name=" + name + ", age=" + age + "]";
}
public people(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
System.out.println("hashCode方法被调用");
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals方法被调用");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
people other = (people) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
输出结果如下,并没有调用hashCode方法
到这里就结束了,我依旧是那个学IT的小学生?
欢迎大佬指点?
|