目录
一.List接口:
二.Set接口:
三.集合部分问题解决:
3.1. 什么是hashcode
3.2 为什么Hashse存放自定义类型元素时,要重写对象中的hashCode和equals方法,才能保证元素唯一。
3.3 List集合扩容机制:
一.List接口:
1.1 List集合概述:
List接口继承自collection接口,我们称实现List接口的对象称之为List集合,在List集合中可以出现重复元素,所有的元素是以线性的存储结构存储。List集合具有一下特点:
1.元素存取有序,即取出元素和存入元素的顺序一致。(线性的存储结构注定他的存取方式)
2.List集合带有索引,跟数组索引一样,可以通过索引找到并且操作List集合中的每一个元素。索引0是第一个元素,索引1是第二个元素,以 此类推.....。
3.List集合中的元素允许重复,可以使用equal方法比较两个元素是否相等。
List接口有两个实现子类arrayList和linkedlist,他们的方法都是来自List中已经定义好的,子类本身不需要额外定义(其他额外需求除外)
1.2 ArrayList集合:
List接口继承自collection接口,我们称实现List接口的对象称之为List集合,在List集合中可以出现重复元素,所有的元素是以线性的存储结构存储。List集合具有一下特点:
1.元素存取有序,即取出元素和存入元素的顺序一致。(线性的存储结构注定他的存取方式)
2.List集合带有索引,跟数组索引一样,可以通过索引找到并且操作List集合中的每一个元素。索引0是第一个元素,索引1是第二个元素,以 此类推.....。
3.List集合中的元素允许重复,可以使用equal方法比较两个元素是否相等。
List接口有两个实现子类arrayList和linkedlist,他们的方法都是来自List中已经定义好的,子类本身不需要额外定义(其他额外需求除外)
1.2.1 ArrayList概述:
1.arrayList集合是list接口的实现子类,继承了list中的方法,并且子类没有其他的太多的改动。
2.arrayList集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以arrayList是最常用的集合。
3.ArrayList底层是由数组实现的,核心的是数组扩容机制,他的长度是可以改变的,并且存储的是引用数据类型的数据。但是也导致一些缺点的出现它可以实现对集合元素的随机访问,但是集合中的元素的移除和插入效率要比另一个实现类低很多,因为他是要通过遍历集合找到元素之后,才插入对应的位置。
1.2.2 ArrayList使用以及常用方法:
Arrarylist位于Java.util包下,系统不会自动导包,所以我们需要手动导入:
java.util.ArrayList;Arraylist类实例化成对象,调用方法:
ArrayList<> arrayList = new ArrayList<>();//实例化对象
Arraylist常用方法:
Arrarylist是list接口的子类,list继承了collection接口所有的方法,同时根据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):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
代码演示:
import java.util.ArrayList; import java.util.LinkedList; public class Shangkelist { public static void main(String[] args) { ArrayList arrayList = new ArrayList();//实例化对象 int sizestart=arrayList.size(); System.out.println("开始的arraylist长度:"+sizestart); arrayList.add(20);//增加元素 arrayList.add("20"); arrayList.add("ob"); arrayList.add(("20")); arrayList.add(1,"200"); int listend=arrayList.size(); System.out.println("结束的长度"+listend); boolean res=arrayList.remove("20"); System.out.println(res); System.out.println("====="); Object str1=arrayList.get(2);//获取元素 // arrayList.remove(0); System.out.println(str1); for(Object str:arrayList){ // System.out.println(arrayList); System.out.println(str); }
注意点:
1.得到集合长度,能更好的根据索引处理集合元素,而得到集合长度的方法不是之前的length()方法,而是size()方法。
2. remove方法不仅可以通过索引删除元素,也可以通过指定对象名删除元素(出现多个相同的元素时会先删除第一个重复的元素)
3.add方法可以指定要加的元素位置和元素,加入到对应的位置(不只是通过加对象名,加在集合最后面)。
1.3 linkedList集合:1.3.1 linkedlist集合概述:
1.linkedList是Java.util包下,是list接口的实现子类
2.linkedList集合数据存储的结构是双向链表链表结构。方便元素添加、删除的集合。
3.linkedlist集合和arraylist集合不同的是:arraylist是线性的存储结构,linkedlist是一个双向链表存储结构,这造成两者的优缺点不同,linkedlist对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢,合适用于元素插入和删除
1.3.2 linkedlist集合的使用以及常用方法:
linkedlist集合和arraylist使用差不多,都是先导入包,实例化对象,调用方法。
Linkedlist常用方法:
public void addFirst(E e):将指定元素插入此列表的开头。
public void addLast(E e):将指定元素添加到此列表的结尾。
public E getFirst():返回此列表的第一个元素。
public E getLast():返回此列表的最后一个元素。
public E removeFirst():移除并返回此列表的第一个元素。
public E removeLast():移除并返回此列表的最后一个元素。
public E pop():从此列表所表示的堆栈处弹出一个元素。
public void push(E e):将元素推入此列表所表示的堆栈。
public boolean isEmpty():如果列表不包含元素,则返回true
注意点:
1.pop方法弹出的元素是堆栈中第一个元素,实际上就是调用removeFirst方法
2.push()方法压入的位置是栈堆第一个位置
3.这些都是linkedlist的特有方法,其他不如add,get等方法都是通用的。
4.linkedlist允许元素重复的。
代码实例:
LinkedList link = new LinkedList(); //添加元素 int sizestar=link.size(); System.out.println("开始长度长度为"+sizestar); link.add("20"); link.add("20"); link.add("30"); link.add("40"); //添加元素到指定位置 link.addFirst(1);//第一个位置 link.addLast(20); //将这个元素推入栈中 link.push("推入元素1"); //指定索引,移除元素 link.remove(1); //弹出元素:弹出的元素是个对象 Object res1=link.pop(); System.out.println("弹出元素1:"+res); int a=link.hashCode(); //结束长度 int size2=link.size(); System.out.println("长度为"+size2); System.out.println("哈希值:"); //循环输出link元素 for(int i=0;i二.Set接口:
2.1 Set接口概述:
1.set接口和list接口都是collection接口的子接口,set接口的方法比collection接口的方法没有什么补充,方法基本一致。但是和list方法有很大的一个不同,就是set集合不允许元素重复并且元素是存取顺序不一定一致,而list方法元素可以重复。
2..set接口有三个实现子类:TreeSet ,LinkedHashSet,HashSet。
注意点:
set接口是不允许元素重复的,但是重复不会报错,只会输出第一个重复的值。
2.2 Hashset集合概述:
1.Hashset是set接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的,他的底层支持是Java.util.Map
2.Hashset是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存储和查找性能。保证元素唯一性的方式依赖于:Hashcode方法和equals方法。
为什么他的元素存取都是无序的?看代码:
public static void main(String[] args) { //不能重复,就算有重复的对像,只会存储一个。 //无序的 HashSetset = new HashSet<>(); set.add(new String("20")); set.add("abc"); set.add("abd"); set.add("aba"); set.add("abc"); //遍历输出 for (String str:set) { System.out.println(str); } } 运行结果:
可以看到他的输出结果和我们的存入顺序不一致。
为什么他的元素不允许重复呢?看代码:
import java.util.HashSet; public class OopshangkeSet { public static void main(String[] args) { //不能重复,就算有重复的对像,只会存储一个。 //无序的 HashSetset = new HashSet<>(); set.add(new String("20")); set.add("abc"); set.add("abc"); set.add("abc"); set.add("abc"); set.add("abd"); set.add("aba"); set.add("abc"); //遍历输出 for (String str:set) { System.out.println(str); } } } 运行结果:
可以看到他的只会输出一个重复的元素。其他的都不会输出,说明其他的重复的元素都没有被存储。
这个不允许重复和无序输出具体原因写在文章最后
2.3 Hashset存储自定义元素:给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一.
代码演示:
重写hashcode和equals方法 */ import java.util.Objects; public class Oopset { private int age; private String name; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Oopset)) return false; Oopset oopset = (Oopset) o; return getAge() == oopset.getAge() && getName().equals(oopset.getName()); } @Override public int hashCode() { return Objects.hash(getAge(), getName()); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Oopset{" + "age=" + age + ", name='" + name + ''' + '}'; } public Oopset(int age, String name) { this.age = age; this.name = name; } }测试类:import java.util.HashSet; import java.util.Objects; public class OopsetTest { public static void main(String[] args) { HashSet2.4:linkedHashset概述:hashSet = new HashSet (); // Oopset student = new Oopset(20, "小强"); // Oopset student1 = new Oopset(21, "小张"); // Oopset student2 = new Oopset(21, "小张"); // Oopset student3 = new Oopset(24, "小李"); hashSet.add(new Oopset(20, "小强")); hashSet.add(new Oopset(21, "小张")); hashSet.add(new Oopset(21, "小张")); hashSet.add(new Oopset(24, "小李")); for (Oopset stu:hashSet) { System.out.println(stu); } } } 我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序
在HashSet下面有一个子类java.util.LinkedHashSet,它是链表和哈希表组合的一个数据存储结构。可以保证存放的元素有顺序。
三.集合部分问题总结以及解决:
3.1. 什么是hashcode
hashcode是通过hash函数也就是某种算法得到的,而hashcode是在hash表中的对应位置,每个对象都有他的hashcode,而一个对象肯定有物理地址,对象的物理地址跟这个hashcode地址不一样,hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址,
那么对象如何得到hashcode呢?通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode
3.2 为什么Hashse存放自定义类型元素时,要重写对象中的hashCode和equals方法,才能保证元素唯一。
明天补充
3.3 List集合扩容机制:明天补充