1.LinkedList
1.1链式结构
LinkedList也是一个集合,是一个链式结构的集合,删除和增加的效率高,
- 因为提供了大量的首尾操作
- 常用的方法:
- void addFirst(E e)—-添加首个元素
- void addLast(E e)—-添加最后元素
- E getFirst()————获取首个元素
- E getLast()————-获取最后元素 ```java package com.igeek_01;
/**
- @author Lynn
- @create 2020-12-08-10:04 */
import javax.sound.midi.Soundbank; import java.util.Iterator; import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
//创建集合对象
LinkedList
//获取元素String name= list.get(1);System.out.println(name);//返回迭代器Iterator<String> iterator= list.iterator();//问取删while (iterator.hasNext()){String thisName= iterator.next();System.out.println(thisName);}System.out.println("---------------------------------");//首尾操作System.out.println(list);list.addFirst("王嘉尔");list.addLast("王一博");System.out.println(list);System.out.println(list.getFirst());System.out.println(list.getLast());//删除list.remove(3);System.out.println(list);}
}
<a name="oxqNN"></a># 2.数据结构<a name="FjPYz"></a>### 2.1Stack-----栈Stack结构的演示- **栈结构---遵循先进后出的原则**- <br />- 对应的方法:- 1.push:压栈---先进后出- 2.pop:弹栈--将元素直接弹出--意味着这个元素在栈中没有了- 3.peek:查询出即将弹出的是哪个元素-检查有没有需要弹出的元素--只看不弹出--- 意味着元素还在栈中- <br />- LinkedList是支持栈结构的- java中专门提供了一个结构--Stack```javapackage com.igeek_02;/*** @author Lynn* @create 2020-12-08-10:20*/import com.sun.prism.shader.Solid_TextureYV12_AlphaTest_Loader;import java.util.LinkedList;public class StackDemo {public static void main(String[] args) {//创建栈结构LinkedList<String> stack=new LinkedList<>();//添加元素/* stack.add("王嘉尔");stack.add("王一博");stack.add("白敬亭");stack.add("刘诗诗");stack.add("赵丽颖");stack.add("谭松韵");*///因为支持栈结构,所以有push方法stack.push("王嘉尔");stack.push("王一博");stack.push("白敬亭");stack.push("刘诗诗");stack.push("赵丽颖");stack.push("谭松韵");//查询结果System.out.println(stack);System.out.println("--------------------------");//获取一个元素,此时由于是栈结构,所以获取的是最后压栈的元素String name=stack.pop();System.out.println(name);System.out.println(stack);System.out.println("--------------------------");//peekString peekname=stack.peek();System.out.println(peekname);System.out.println(stack);}}
2.2Queue—队列
队列结构演示:
- 队列结构支持:先进先出的原则
- LinkedList支持队列结构!!
- 因为这个LinkedList本身是链式结构,所以添加和删除比较灵活,而栈和队列都是
- 数据结构中的操作,所以利用LinkedList支持比较方便
- 对应的方法:
- offer:加入队列
- poll:(获取的是最早进入的元素)离开队列—该元素已经不在队列中了
- peek:查询出即将离开队列的是哪个元素—只看不离开—该元素还在队列中 ```java package com.igeek_02;
/**
- @author Lynn
- @create 2020-12-08-10:36 */
import java.util.LinkedList;
public class QueueDemo {
public static void main(String[] args) {
//利用LinkedList支持队列
LinkedList
System.out.println("----------------------------");//获取一个元素,此时由于是队列结构,所以获取的是最早进入的元素System.out.println(queue.poll());System.out.println(queue);System.out.println("----------------------------");//peekSystem.out.println(queue.peek());System.out.println(queue);}
}
<a name="5d62p"></a># 数组结构和链表结构<a name="aQUKT"></a>## 1.1 ArrayList数组实现的原理数组实现的特点:查询快,增删慢<br />原因:<br /> 查询快:由于数组的索引支持,那么可以通过索引直接计算出元素的地址值,因此就可以直接通过元素的地址值获取到指定的元素<br />增删慢:由于在添加元素的时候,实际上底层会先创建一个新数组(新数组的长度为原数组的长度+1),那么在添加新元素的时候,先需要对数组中原有的数据进行拷贝,其次在末尾进行添加新的元素<br />因此,这样操作的效率的极低的(删除元素 刚好和添加的操作相反)<a name="2L8B2"></a>## 1.2 LinkedList链表实现的原理链表结构:查询慢,增删快<br />查询慢:由于不能直接找到元素的地址,需要上一个元素推导出下一个元素的地址,<br />这种查询速度较慢<br />增删快:在添加的时候,只需要更改元素所记录的地址值即可<a name="VEAlV"></a># 3.HashSet集合HashSet也是一个集合,**不包含重复的元素和相同的元素,无序的,不提供索引(下标**),- 所以不能通过下标获取元素,只能通过**迭代器访问---增强for循环**- <br />- HashSet怎么做到不重复的?- 1.首先在元素存放进这个集合之前会通过HashCode()方法算出哈希值(int类型)- 2.比较当前这个哈希值在集合中是否已经存在,如果存在就不保存- <br />- 所以HashSet称之为**无序不可重复**集```javapackage com.igeek_03;/*** @author Lynn* @create 2020-12-08-11:05*/import java.util.HashSet;import java.util.Iterator;/*** HashSet也是一个集合,不包含重复的元素和相同的元素,无序的,不提供索引(下标),* 所以不能通过下标获取元素,只能通过迭代器访问---增强for循环** HashSet怎么做到不重复的?* 1.首先在元素存放进这个集合之前会通过HashCode()方法算出哈希值(int类型)* 2.比较当前这个哈希值在集合中是否已经存在,如果存在就不保存** 所以HashSet称之为无序不可重复集*/public class HashSetDemo {public static void main(String[] args) {//创建集合对象HashSet<String> set=new HashSet<>();//向集合中添加元素--无序,不可重复set.add("王嘉尔");set.add("王嘉尔");set.add("王一博");set.add("赵丽颖");set.add("白敬亭");set.add("白敬亭");set.add("谭松韵");set.add("刘诗诗");//打印结果System.out.println(set);//获取元素--只能使用迭代器Iterator<String> iterator= set.iterator();while (iterator.hasNext()){//推荐向下转型--强类型转换---目的是为了增加代码的健壮性---//转成最后需要接受的类型String thisName = (String)iterator.next();System.out.println(thisName);}System.out.println("----------------------");//增强for循环底层就是一个迭代器for (String name:set){System.out.println(name);}//普通for循环for (int i = 0; i < set.size() ; i++) {//HashSet没有下标,所以不提供get方法,get方法根据下标获取对应元素// System.out.println(set.get(i));}}}
练习
package com.igeek_03;import java.util.HashSet;import java.util.Iterator;/*** @author Lynn* @create 2020-12-08-11:25*//*** fdasffkdsajfasFJKFDSAJKdfefoeaf* <p>* 分析:* 1.将字符串拆分为一个个单个的字符* 2.判断字符是否为字母* 如果是字母,放到一个set集合中* 3.查看set集合的长度*/public class HashSetTest {public static void main(String[] args) {//准备一个字符串String s = "fdasffkdsajfasFJKFDSAJKdfefoeaf";//定义一个不含重复元素的集合HashSet<Character> set = new HashSet<>();//拆分字符串char[] chars = s.toCharArray();//遍历---无下标的for (char c : chars) {//判断字符是否为字母,如果是字母,放到一个set集合中if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){set.add(c);}}//查看System.out.println(set);System.out.println(set.size());}}
4.ArrayList中有一个方法:Contains用来判断是否有重复的元素
boolean Contains(Objects o)—判断集合中是否有指定的元素
- 为了实现这个功能,我们需要新建一个实体类,是Object的子类,具备了equals方法
- Contains方法会调用参数的equals方法,依次为集合中的已经存在的对象进行比较
- 例如:新建一个Person子类继承Object。直接调用equals方法 ```java package com.igeek_04;
/**
- @author Lynn
- @create 2020-12-08-14:23 */
/**
实体类 */ public class Person { private String name; private int age;
public Person() { }
public Person(String name, int age) {
this.name = name;this.age = 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 "Person{" +"name='" + name + '\'' +", age=" + age +'}';
}
//重写equals方法
/**
- 目的是比较两个对象像不像
- @param obj
@return */ @Override public boolean equals(Object obj){ System.out.println(“equals方法被调用了”);
//this:表示contains方法的参数对象 //obj:集合中原有的对象 //将Object类型的obj强制转换为子类类型(向下转型) Person otherP=(Person)obj;
//重写比较规则 //比较的是当前的对象的属性:姓名,年龄 if (!this.getName().equals(otherP.getName())){
return false;
} if (this.getAge()!= otherP.getAge()){
return false;
} //如果上面两个都不是false,则返回true return true; } }
java package com.igeek_04;
/**
- @author Lynn
- @create 2020-12-08-14:19 */
import java.util.ArrayList;
public class ArrayListContainsDemo {
public static void main(String[] args) {
//创建集合
ArrayList
//判断--Contains方法中大小写敏感System.out.println(list.contains("jack"));//falseSystem.out.println("==================================");//对象比较ArrayList<Person> list2=new ArrayList<>();list2.add(new Person("宋远桥",45));list2.add(new Person("俞莲舟",40));list2.add(new Person("张翠山",32));Person p=new Person("殷素素",30);list2.add(p);//equals方法默认的比较对象的方式是比较地址值,即==System.out.println(list2.contains(new Person("宋远桥",45)));//false--比较的是地址值
// System.out.println(list2.contains(p));//true
}
}
<a name="45QV3"></a># 5.HashSet判断元素唯一性HashSet这个集合中添加元素的方法在执行添加的时候,会判断元素是否已经存在:- HashSet判断元素唯一性的规则:- 1.把对象加入到HashSet的时候,会先使用对象的HashCode方法,来生成一个哈希值,- 判断对象加入的位置- 2.如果比较的位置,没有其他对象存在,则判断元素不同,可以加入新的对象- 3.如果比较的位置,有其他对象存在,接着比较HashCode值和equals比较结果- 返回true则相同,不能存入新的对象,如果是false则不同,添加新的对象- <br />- 需求:- 要求比较两个对象的属性和内容是否相同,而非比较对象的地址值- 此时我们可以重写Person类中的HashCode方法和equals方法,将Object类中的方法重写<a name="L0qWW"></a>### 重写equals方法```java/** 如果没有重写该equals方法,则比较地址值.* 我们希望比较两个对象时,比较属性内容,所以重写该方法.*//*** @Title: equals* @Description: Person对象比较是否相等的方法* @param obj* @return* @see java.lang.Object#equals(java.lang.Object)*/@Overridepublic boolean equals(Object obj) {System.out.println("equals方法被调用了");//this:contains方法的参数对象//obj:集合当中原有元素//将Object类型的obj强转为子类类型Person otherP = (Person)obj;//比较姓名if(!this.name.equals(otherP.name)) {return false;}//比较年龄if(this.age != otherP.age){return false;}//如果所有属性值均相同,就返回truereturn true;}
重写HashCode方法
//没有重写hashCode方法时,hashCode方法继承父类方法,返回的是地址值//重写hashCode方法,通过属性值返回一个整数数字//即对象的hashCode值,就是各个属性的hashCode值之和//引用数据类型属性,调用hashCode方法回去//基本数值类型属性,直接就是数值本身/*** @Title: hashCode* @Description: Person对象的hashCode值算法方法* @return* @see java.lang.Object#hashCode()*/@Overridepublic int hashCode() {//张三 18 >> 56*系数 + 18 = 74//李四 56 >> 18*系数 + 56 = 74//理想上,不同属性值应该返回不同的hashCode值,可以在每次结果后乘以一个固定系数,避免该情况发生//定义变量,记录要返回的hashCode值int thisHashCode = 0;//获取name属性的hashCode值thisHashCode += name.hashCode()*17;//获取age数只给你的hashCode值thisHashCode += age;return thisHashCode;}
package com.igeek_05;/*** @author Lynn* @create 2020-12-08-14:23*//*** 实体类*/public class Person1 {private String name;private int age;public Person1() {}public Person1(String name, int age) {this.name = name;this.age = 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}//重写equals方法/*** 目的是比较两个对象像不像* @param obj* @return*/@Overridepublic boolean equals(Object obj){System.out.println("equals方法被调用了");//this:表示contains方法的参数对象//obj:集合中原有的对象//将Object类型的obj强制转换为子类类型(向下转型)Person1 otherP=(Person1)obj;//重写比较规则//比较的是当前的对象的属性:姓名,年龄if (!this.getName().equals(otherP.getName())){return false;}if (this.getAge()!= otherP.getAge()){return false;}//如果上面两个都不是false,则返回truereturn true;}//重写HashCode方法public int hashCode(){System.out.println("hashCode方法被调用了");//定义一个变量int thisHashCode=0;//张三,18 56*系数+18=74//李四,56 18*系数+56=74//获取name属性的HashCode值thisHashCode+=this.name.hashCode()*17;//获取age属性的HashCode值,就是age本身thisHashCode+=this.age;return thisHashCode;}}
package com.igeek_05;/*** @author Lynn* @create 2020-12-08-15:07*/import java.util.HashSet;public class HashSetAddDemo1 {public static void main(String[] args) {HashSet<Person1> set=new HashSet<>();Person1 p=new Person1("张三丰",120);Person1 p2=new Person1("郭襄",100);Person1 p3=new Person1("杨过",110);//添加到集合中set.add(p);set.add(p2);set.add(p3);// System.out.println(set);//调用equals方法//再次调用add方法添加新元素--不可以添加原有的元素set.add(new Person1("郭襄",100));System.out.println(set);}}
Java单列集合框架之总结&体系图
单列集合体系图

Collection:所有单列集合的直接或间接接口,其指定了所有集合应该具备的基本功能。
List:元素可重复,有序,带索引
Set:元素不能重复,没有索引
ArrayList(重要) :底层是数组结构。ArrayList的出现替代了Vector,增删慢,查找快
LinkedList(重要):底层是链表结构。同时对元素的增删操作效率很高
HashSet(重要) :底层是哈希表结构。在不重复的基础上无序
LinkedHashSet:底层是哈希表结构结合链表结构。在不重复的基础上可预测迭代顺序
