1.集合
1.1什么是集合?
在我们面向对象语言的学习中对事物的表现都是以对象的形式呈现的,然而为了对多种对象进行操作,java为我们提供了集合类
1.2集合的特点
①集合只能用于存储对象,且长度可以改变
②集合可以存储不同类型的对象
1.3集合与数组的区别
既然说了集合也可以存储对象,我们之前学过的数组也可以存储对象,那他们二者的区别在哪呢?
①长度不同。集合长度可以改变,数组长度不能改变。
②存储内容不同。集合可以存储多种类型数据,而数组存储的数据类型相同。
③类型不同。集合只能存储引用数据类型,数组可以存储引用数据类型和基本数据类型。
1.4注意事项:
集合是用来存储对象的,但是我们也有各种需求:
比如:要求学生姓名不能重复,或者按照年龄排序。
针对不同的需求,我们会不同的集合来存储,它们的区别就是数据底层结构不同。
我们将数据存储好了以后,我们还需要使用它,那么这样一来,就形成了一套集合体系。
2.Collection
2.1概述:
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
2.2常见方法:
①添加方法
public class CollectionTest {
public static void main(String[] args) {
//创建对象(多态)
Collection c = new ArrayList();
Collection c2= new ArrayList();
//添加方法
c.add("hello");
c.add(123);
c.add("world");
System.out.println(c);
c2.add("hi");
c2.add("java");
c.addAll(c2);//直接将才c2集合添加到c中
System.out.println(c);
}
}
结果如下:
②删除方法
c2.clear();//删除集合中全部元素
System.out.println(c2);
c.remove(123);//删除集合中指定元素
System.out.println(c);
c2.add("pop");
c.addAll(c2);
System.out.println(c);
c.removeAll(c2);//删除集合中另一个集合
System.out.println(c);
结果如下:
③判断方法
boolean flag = c.contains("cc");//判断是否包含
System.out.println(flag);
boolean flag2 = c.isEmpty();//判断是否为空
System.out.println(flag2);
结果如下:
④获取方法
int num = c.size();//获取集合长度
System.out.println(c);
System.out.println(num);
结果如下:
2.3简单面试题
数组有没有length()方法?----false
集合有没有length()方法?----false
字符串有没有length()方法?----true
2.4数组与集合的转化
如果我们要求遍历集合,那么你们会想到什么办法呢?数组可以通过索引来遍历,可是我们的集合没有索引,这时候大家会不会想到将集合转化为数组,再遍历呢?
public class CollectionTest {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("hello");
c.add(123);
c.add("world");
//定义一个数组接收
Object [] objects = c.toArray();//这里的toArray()方法可以将我们的集合转化为数组
System.out.println(Arrays.toString(objects));//再通过Arrays类的方法即可遍历
//数组转化为集合
//asList();方法
}
}
结果如下:
3.List类
3.1概述:
元素有序,并且允许元素重复的集合
3.2特有方法:
List类中大部分都和Collection方法相同,这里我们就介绍List的特有方法
public class ListTest {
public static void main(String[] args) {
List list = new ArrayList();
List list2 = new ArrayList();
//添加
list.add("hello");
list.add("world");
list.add("java");
list.add(1,"zjd");//原索引位置元素后移
System.out.println(list);
list2.add(123);
list.addAll(1,list2);//指定索引处,添加一个集合,原来索引后移
System.out.println(list);
//获取
System.out.println("________________________________");
Object o = list.get(2);
String s = (String) o;//默认了toString
System.out.println(s);
//修改
System.out.println("________________________________");
Object o1 = list.set(1,"txw");
System.out.println(o1);//返回被替换的元素
//截取
System.out.println("_________________________________");
List newList = list.subList(1,3);
System.out.println(newList);
System.out.println(list);
//删除
System.out.println("_________________________________");
Object o2 = list.remove(1);
System.out.println(o2);
}
}
结果如下:
3.3面试题:
ArrayList:数组
特点 查询快,增删慢
线程不安全,效率高
Vector:数组
特点 查询快,增删慢
线程安全,安全性高,但效率低
LinkedList:链表
特点 查询慢,增删快
线程不安全,效率高
问题:在开发中是如何决定使用哪个集合子类?
首先,我们先考虑对于数据安全性要求高不高?
高 Vector
低
ArrayList
LinkedList
如果在效率低的情况下,再考虑数据 查询和增删的侧重
4.ArrayList
4.1概述:
List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括null在内的所有元素。
4.2特有方法:
这里我们同样只是学习它的特有方法
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("hello");
arrayList.add("world");
arrayList.add("java");
arrayList.add("java");
//特有方法
int i = arrayList.indexOf("java"); //查看指定首次出现索引的元素,没有返回-1
System.out.println("首次出现索引:"+i);
int i1 = arrayList.lastIndexOf("java");//同上,最后一次出现的
System.out.println("最后一次出现索引:"+i1);
//toArray 转化数组
Object[] objects = arrayList.toArray();
System.out.println(Arrays.toString(objects));
System.out.println("_________________________________________");
//迭代器遍历
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()){
String s = (String) iterator.next();
System.out.println(s);}
//for
System.out.println("_________________________________________");
for(Iterator iterator1 = arrayList.iterator();iterator1.hasNext();){
String s1 = (String) iterator1.next();
System.out.println(s1);
}
}
}
结果如下:
4.3代码练习:
//接下来,我们来做一个练习:自定义对象去重
//思路分析:1.我们先创建一个学生类,方便我们调用
// 2.创建一个ArrayList集合对象,并加入Student的元素
// 3.创建一个新ArrayList集合
// 4.通过迭代器遍历旧集合,遍历一个便加入到新集合中,当重复时则不添加
//首先,我们先定义一个学生类
public class Student{
private String name;
private int age;
//构造函数
public Student() {
}
public Student(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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
name.equals(student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//我们再定义一个测试类
public class ArrayTest {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(new Student("tom",18));
arrayList.add(new Student("zjd",20));
arrayList.add(new Student("txb",19));
arrayList.add(new Student("tom",18));
ArrayList newArrayList = new ArrayList();
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()){
Student s = (Student)iterator.next();
if(!newArrayList.contains(s)){
newArrayList.add(s);
}
}
System.out.println(newArrayList);
}
}
结果如下:
5.LinkedList
5.1概述:
List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。
除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。
这些操作允许将链接列表用作堆栈、队列或双端队列。
5.2特有方法:
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("hello");
linkedList.add("world");
linkedList.add("java");
System.out.println(linkedList);
linkedList.addFirst(123);//将指定元素插入此列表的开头。
linkedList.addLast(456);//将指定元素添加到此列表的结尾。
System.out.println(linkedList);
System.out.println("________________________________");
Object first = linkedList.getFirst();//获取第一个元素
Object last = linkedList.getLast();//获取最后一个元素
System.out.println(first);
System.out.println(last);
System.out.println("____________________________________");
Object o = linkedList.removeFirst();//移除第一个元素
Object o1 = linkedList.removeLast();//移除最后一个元素
System.out.println(o);
System.out.println(o1);
}
}
结果如下:
5.3代码练习:
//用ListedList模拟栈结构,并测试
public class LinkedListDemo2 {
public static void main(String[] args) {
MyStack myStack = new MyStack();
myStack.add("hello");
myStack.add("world");
myStack.add("java");
System.out.println(myStack.get());
System.out.println(myStack.get());
System.out.println(myStack.get());
}
}
class MyStack{
private LinkedList linkedList;
public MyStack(){
this.linkedList = new LinkedList();
}
public void add(Object o){//添加
linkedList.addFirst(o);
}
public Object get(){//获取
return linkedList.removeFirst();
}
}
结果如下:
6.面试题
ArrayList和LinkedList的区别?
经常看面经的小伙伴肯定知道,这是一道面试官经常问到的面试题,下面我就来给大家分析一下:
1.概念不同。
ArrayList:基于动态数组的数据结构
LinkedList:基于链表的数据结构
2.访问速度不同。
ArrayList:可以依靠索引访问,速度快
LinkedList:要依靠指针的移动,速度慢
3.内存占比。
LinkedList要比ArrayList更占内存,LinkedList的节点不仅存储数据,还有上下两个指向next和prev
4.增删速度不同。
ArrayList:因为底层实现基于数组,所以要移动大量数据才可完成,速度慢
LinkedList:直接通过链表的next改变指向即可完成增删,速度快