List、Set、数据结构、Collections
一.数据结构:
1.什么是数据结构:
一种数据的存储方式
2.常见的4+1种数据结构
堆栈结构:
它是只有一个开口的容器结构
特点:
先进后出(FILO)
例子:弹夹,桶装可比克
队列结构:
它是两端都有开口的容器结构
特点:
先进先出(FIFO)
例子:
安检机
数组结构:
数组结构在内存中是一块连续的区域
特点:
对元素的查询非常快(原因:有下标)
对元素的增加和删除非常慢
过程:
增加的过程:
要添加数组的长度,创建新的数组
进行复制 旧数组
添加新元素
再销毁旧数组(JVM里边有垃圾回收器)
删除的过程:
减少数组的长度,创建新的数组
进行复制
再销毁旧数组(JVM里边有垃圾回收器)
链表结构:
分开环链表,闭环链表
单列表:指针域:数据域
双列表:指针域:数据域:指针域
链表结构中,每一个元素我们一般称为节点
组成部分:
数据域,指针域
链表结构在内存是可以不连续的
优点:
可以提高内存的利用率
特点:
查询慢
增删快
哈希表结构:(数组结构和链表结构的组合)
特点:
查询快
增删快
红黑树结构:
红黑树结构的查找效率非常快
二.List接口
1.List接口的特点:
a.有序:存储的顺序和取出的顺序是一致的(比如:保存时1 2 3 取出时1 2 3 )
b.有索引:说明有下标(就是跟下标相关方法)
增:add(元素),add(int index,元素)
删:remove(元素),remove(int index);
改:set(int index,新元素)
查:get(int index);
c.元素可重复:集合中可以保存两个相同的元素
2.List接口中常用的方法以及常用子类
增:add(元素),add(int index,元素)
删:remove(元素),remove(int index);
改:set(int index,新元素)
查:get(int index);
具体的常用实现类:
ArrayList,LinkedList,Vector
3.ArrayList的数据结构以及使用
底层数据结构:数组结构(查询快,增删慢)
特有方法:无
4.LinkList的数据结构以及使用
底层数据结构:链式结构(查询慢,增删快)
特有方法:(大量和首位操作方法)
-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();从此列表所表示的堆栈处弹出一个元素(弹出,删除元素)和removeFirst是一样的功能
-public void push(E e);将元素推入此列表所表示的堆栈(推入,添加元素)和addFirst是一样的功能
三.Set接口
1.Set接口的特点:
a.无序:指的是元素存储顺序和取出顺序不一定一致(LinkedHashSet除外)
b.索引:说明集合没有下标,只能通过迭代器(增强for循环)
c.元素不可重复:集合中只能有一个相同的元素
2.Set接口的常用方法以及常用子类
特有方法:无
常用实现类:
HashSet,LinkedHashSet,TreeSet
3.HashSet的数据结构以及使用
底层数据结构:哈希表结构(查询快,增删快)
如果哈希结构大的话:会加上红黑树结构
所有的哈希表结构 都有一个特点:保证元素是唯一的。
4.哈希表结构的介绍(扩展)
只有底层是哈希表结构,就能保证元素的唯一的吧!!!
对象的哈希码值(对象的“数字指纹”)-----每一个对象都有一个哈希值
a.java中所有的对象都有哈希码值,怎么得到:
调用 对象名.hashcode()方法即可得到
下面给出几个常用的哈希码的算法。
1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串所在的堆空间相同,返回的哈希码也相同。
3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可见,2个一样大小的Integer对象,返回的哈 希码也一样。
b.我们平时说的地址值,其实是假的!!!
获取到对象的哈希值,给你转成16进制,骗你说这是地址值
注意:
java中其实是有地址值的,在对象名中,只是java打印不出地址值。
结论:哈希表结构如何保证元素的唯一性?
过程:
首先比较两个元素的哈希码值
如果哈希码值相同,再调用equals方法查看是否为true
只有哈希码值相同,并且equals方法也返回true,才判断这两个元素是重复的,不添加。
思考问题:
那么不同的对象,哈希值可能相同吗?
如果对象没有重写hashCode,那么肯定是调用Object的hashCode
而hashCode的返回值是int(42亿种),对象有无数个,所有哈希值是有可能相同(可能性低)
如果对象重写了hashCode,那就要看如何重写了
5.LinkedHashSet的数据结构以及使用
底层数据结构:链表和哈希表(数组+链表+红黑树【当元素超过8个,那么这个链表结构就会变身成红黑树】)
特点:有序,无索引,元素不可重复
练习:使用哈希表结构,保存自定义对象
如果要保证自定义对象的唯一性,必须重写对象hashCode和equals
6.可变参数
JDK1.5出现的新特性
可变参数:可变参数指的是参数的个数可以随便写(而不是参数类型)
格式:
public 返回值类型 方法名(数据类型...变量名){
}
例子:
public static void main(String[] args) {
//调用
System.out.println(getSum(10));
System.out.println(getSum(11, 51));
System.out.println(getSum(102, 12, 45));
System.out.println(getSum());
}
//可变参数指的是参数的个数
public static int getSum(int...nums){
int sum=0;
for (int num : nums) {
sum+=num;
}
return sum;
}
结果:
10 23 39 0 Process finished with exit code 0
本质:
可变参数的底层就是数组,打印时,通过遍历来打印。
注意事项:
一个方法只能有一个可变参数
一个方法中如果有可变参数和正常的参数,那么可变参数必须写到最后
四.Collections
1.Collections的介绍
Collections是集合工具类,专门方便我们操作集合
Arrays是数组工具类,专门方便我们操作数组
2.常用功能方法
-public static <T> boolean addAll (Collection<T> c,T... elements);将所有指定元素添加到指定 collection 中。
例子:
public static void main(String[] args) {
//1.添加所有
ArrayList<String> names=new ArrayList<String>();
//添加
Collections.addAll(names,"小苗","java","强");
// for (String name : names) {
// System.out.println(name);
// }
System.out.println(names);
}
结果:
[小苗, java, 强] Process finished with exit code 0
-public static void shuffle(List<?> list);打乱顺序:打乱集合顺序(只有list才可以排)
-public static<T> void sort(List<T> list);将集合中元素按照默认规则升序排序
3.扩展1:Comparable<T>自然排序接口
Collections的sort对集合进行排序时,必须满足集合的泛型需要实现一个接口Comparable
实现Comparable接口,重写方法,比较方法
this和传入的对象进行比较
返回值正数:代表this大
返回值负数:代表传入的对象大
返回值为0:代表相同
升序:
this减去传入的数据
4.扩展2:Comparator<T>比较器排序接口
Collections的sort方法,除了接收集合之外,还可以接收一个比较器Comparator接口的实现类对象
这时候自然排序接口就起不了作用。
Comparator接口
创建接口的实现类对象------用匿名内部类
new Comparator
升序就 是1的减去2 的
总结:两种比较方式的优劣
第二种比较器排序比较灵活
因为第一种比较已经写死比较规则
第二种比较 由于比较规则由程序员自己传递,所以可以随时变换比较规则
例子:
public class Girl implements Comparable<Girl>{
int age;
String name;
public Girl(){
}
public Girl(int age, String name) {
this.age = age;
this.name = name;
}
//重写方法比较方法
public int compareTo(Girl o) {
//this和o的比较
//记住:返回值正数 代表this大
// 返回值负数 代表o大
// 返回值0 代表相等
return this.age-o.age;
//升序就是 我 减它
}
@Override
public String toString() {
return "Girl{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
实现:
public static void main(String[] args) {
//排序自定义类型
ArrayList<Girl> gg=new ArrayList<Girl>();
//保存自定义对象
gg.add(new Girl(12,"add"));
gg.add(new Girl(14,"frcdc"));
gg.add(new Girl(11,"eec"));
gg.add(new Girl(17,"ceex"));
//排序
// Collections.sort(gg);//按照Comparable接口自然排序
Collections.sort(gg, new Comparator<Girl>() {
public int compare(Girl o1, Girl o2) {
//升序就是1减2
return o1.name.length()-o2.name.length();
}
});//根据比较器进行排序
System.out.println(gg);
}
结果:
[Girl{age=12, name='add'}, Girl{age=11, name='eec'}, Girl{age=17, name='ceex'}, Girl{age=14, name='frcdc'}]
Process finished with exit code 0
5.排序练习(代码实现)
创建一个学生类,存储到ArrayList集合中,
要求按照学生的年龄升序排序,
如果年龄相同那么按照名字的第一个字母升序排序
代码:
public class Student implements Comparable<Student>{
int age;
String name;
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;
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public int compareTo(Student o) {
return 0;
}
}
代码:
public static void main(String[] args) {
ArrayList<Student> list=new ArrayList<Student>();
list.add(new Student(44,"af"));
list.add(new Student(14,"fsf"));
list.add(new Student(15,"rv"));
list.add(new Student(16,"sef"));
list.add(new Student(16,"ugc"));
Collections.sort(list, new Comparator<Student>() {
public int compare(Student o1, Student o2) {
if(o1.age==o2.age ){
return o1.name.charAt(0)-o2.name.charAt(0);
}
return o1.age-o2.age;
}
});
System.out.println(list);
}
结果:
[Student{age=14, name='fsf'}, Student{age=15, name='rv'}, Student{age=16, name='sef'}, Student{age=16, name='ugc'}, Student{age=44, name='af'}]
Process finished with exit code 0
面试题:
向哈希表结构的集合中,添加重复元素时,根本添加不进去,add方法的返回值是false
浙公网安备 33010602011771号