java基础知识点总结(二)——Object、数组、集合、HashMap
一、Java集合框架图
二、集合与数组的区别:
集合 数组
长度 集合长度可变 数组长度固定
内容区别 集合只能是引用类型 基本类型和引用类型都可以
集合可以存储不同类型(
元素内容 但一般也是存储一种类型, 数组只能存放一种数据类型
使用泛型时会指定类型)
集合比较:
注意:加载因子:扩容因子=已存容量/现有容量。0.75表示当使用容量达到3/4时扩容
三、Collection集合
1.常用方法:
🔺🔺🔺🔺🔺重点:
addAll():list1.addAll( list2 ); 这句话的意思是:将list2集合中的所有的元素都一个个的添加进list1中。这样改变了list1的元素组成,但是没有改变list2的元素组成。
removeAll(): list1.remove(list2) ; 这句话的意思是:list1集合与list2集合 先 找到 交集,然后 在 list1中删除 交集 ,然后将删除交集后的list1重新赋给list1,list2中的元素不变,然后打印list1,这样就会输出 删除交集后的 list1 。 removeAll删除的是 两个集合的交集 。
containsAll(): boolean flag = list1.containAlls(list2) ; 查看 list1中是否包含所有的list2中的元素,如果 list1 集合中 包含所有 的 list2集合中所有的元素,那么就返回 true ,否则返回 false 。
retainAll(): boolean flag = list1.retainAll(list2) ; list1 和 list2 两个集合 先取 交集 。 然后 将交集 赋给 list1 , 如果 list1集合元素组成发生了变化,那么就返回 true ,否则返回 false 。 特殊情况: list1 和 list2 两个集合 完全相同,所以 list1 和list2 的交集 就是他们 本身,把交集 赋给 list1时 ,list1 没有发生任何的变化,所以返回 false 。
综上所述:retainAll()中 ,只要list1发生变化,就返回 true,不发生变化就返回false 。
代码描述:
package cn.rjxy.tao16.Test01;
import java.util.ArrayList;
import java.util.Collection;
/**
* 测试Collection接口的常用方法
* @author 陶沅玱
*
*/
public class Test1 {
// 测试collection接口的常用方法
public static void main(String[] args) {
Collection<String> coll = new ArrayList<String>();
// Collection<Integer> coll1=new ArrayList<>();
// coll1.add(1);
coll.add("你好");
coll.add("java");
// 测试是否为空,如果集合没有元素那个集合就是空,返回true,有元素返回false
boolean b = coll.isEmpty();
System.out.println(coll); // [你好, java]
System.out.println(b); // false
// 返回集合元素的个数
System.out.println(coll.size()); //2
// 集合是否包含这个元素 ,有则返回true
System.out.println(coll.contains("java")); //true
// 删除元素,删除成功返回true
System.out.println(coll.remove("java")); //true
System.out.println(coll.size()); //1
// 清空元素
coll.clear();
System.out.println(coll.isEmpty()); //true
}
}
package cn.rjxy.tao16.Test01;
import java.util.ArrayList;
import java.util.Collection;
public class Test3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Collection<String> c1 = new ArrayList<>();
c1.add("c");
c1.add("c++");
c1.add("java");
Collection<String> c2 = new ArrayList<>();
c2.add("jsp");
c2.add("php");
boolean b = c1.contains(c2);
System.out.println(b); //false
//把c2的数据都值给c1,
c1.addAll(c2);
c1.forEach(a -> System.out.print(a + "\t")); //c c++ java jsp php
System.out.println();
//从c1中移除与c2相同的元素(指地址相同)
c1.removeAll(c2);
c1.add("java");
c1.forEach(a -> System.out.print(a + "\t")); //c c++ java java
System.out.println();
c1.removeAll(c2);
c1.forEach(a -> System.out.print(a + "\t")); //c c++ java java
}
}
2.遍历集合的三种方式:
package cn.rjxy.tao16.Test01;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;
/**\
* 遍历Collection接口的三种方式
* @author 陶沅玱
*
*/
public class Test2 {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<String>();
coll.add("你好");
coll.add("java");
// 遍历集合,1.增强for循环
for (String str : coll) {
System.out.println(str);
}
// 遍历集合,2迭代器
Iterator<String> it = coll.iterator();
// .hasNext()判断当前集合里面是否有元素,有就返回true
// .next()返回下一个元素
while (it.hasNext()) {
System.out.println(it.next());
}
// 遍历集合,3.lambda表达式
coll.forEach(e -> System.out.println(e));
//方式三的匿名内部类表达上市
coll.forEach(new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println(t);
}
});
System.out.println();
//也是lambda表达式
coll.forEach(System.out::println);
}
}
四、ArrayList集合
List集合的特征:List的特征是其元素以线性方式存储,集合中可以存放重复对象。
1.定义
实现了List接口,代表长度可以改变得数组。可以对元素进行随机的访问,向ArrayList()中插入与删除元素的速度慢。
2.创建方式
//定义存放String类型的集合
List<String> list = new ArrayList<>();
3.使用方法
同Collection集合的操作一样
package cn.rjxy.tao16.Test02;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
list.add(0, "abc");
list.forEach(e -> System.out.print(e + "\t")); //abc hello
System.out.println();
//修改hello
list.set(1, "111");
list.forEach(e -> System.out.print(e + "\t")); //abc 111
System.out.println();
//删除
list.remove(0);
list.forEach(e -> System.out.print(e + "\t")); //111
System.out.println();
System.out.println(list.get(0)); //111
}
}
4.ArrayList集合与数组的转换
package cn.rjxy.tao16.Test02;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 集合与数组的转换
* @author 陶沅玱
*
*/
public class Test3 {
//把集合转换成数组
public static void test1() {
//创建一个集合
List<Integer> list1 = new ArrayList<>();
list1.add(2);
list1.add(5);
list1.add(8);
//方法一:把集合转换成数组 toArray()->该方法返回的是一个 Object类型的数组
//Integer[] intArray = (Integer)list1.toArray(); 编译时不会报错,运行时报错java.lang.ClassCastException
Object[] objArray = list1.toArray();
System.out.println(Arrays.toString(objArray)); // [2, 5, 8]
//方法二:toArray(T[] t); 在方法参数中指定数组类型,返回值即为该类型数组
Integer[] intArray = list1.toArray(new Integer[list1.size()]);
System.out.println(Arrays.toString(intArray)); // [2, 5, 8]
List<String> list2 = new ArrayList<>();
list2.add("hello");
list2.add(0, "java");
String[] strArray = list2.toArray(new String[list2.size()]);
System.out.println(Arrays.toString(strArray)); //[java, hello]
}
//把数组转换成集合
public static void test2() {
List<String> list1 = Arrays.asList("java", "hello", "tao");
System.out.println(list1); //[java, hello, tao]
//用这种方式生成的集合不能使用add、remove等方法,
//list1.add("xx"); 编译时不报错,运行时报错java.lang.UnsupportedOperationException
}
public static void main(String[] args) {
test2();
}
}
5.给集合进行排序
注意:Arrays.sort(数组)
Collections.sort(List)
//给集合进行排序
public static void test2() {
List<String> list1 = Arrays.asList("java", "hello", "tao");
System.out.println(list1); //[java, hello, tao]
//用这种方式生成的集合不能使用add、remove等方法,
//list1.add("xx"); 编译时不报错,运行时报错java.lang.UnsupportedOperationException
//给集合排序,使用Collections类中的sort方法
Collections.sort(list1);
System.out.println(list1); //[hello, java, tao]
//排序的两种方式
//Comparable(在类内部实现,使类直接及实现该接口) 和 Comparator
//https://www.cnblogs.com/szlbm/p/5504634.html
list1.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
return o1.compareTo(o2);
}
});
System.out.println(list1); //[hello, java, tao]
}
🔺使用Comparable、 Comparator进行排序
<1.Comparator
Comparator可以认为是是一个外比较器,个人认为有两种情况可以使用实现Comparator接口的方式:
1、一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较
2、一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式Comparator接口里面有一个compare方法,方法有两个参数T o1和T
o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:
1、o1大于o2,返回正整数
2、o1等于o2,返回0
3、o1小于o3,返回负整数
▲案例:
按照学生成绩排序
1.定义Student类
两个变量:name,score
方法:
2.定义集合,3个student对象,添加到集合
3.使用sort方法排序,排序是指定排序规则
4.输出排序后的集合
package com.rjxy.day16.Test2;
public class Student {
private String name;
private int grade;
public Student(String name, int grade) {
super();
this.name = name;
this.grade = grade;
}
public String getName() {
return name;
}
public int getGrade() {
return grade;
}
@Override
public String toString() {
return "Student [name=" + name + ", grade=" + grade + "]";
}
}
package com.rjxy.day16.Test2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Student> stuList = new ArrayList<>();
stuList.add(new Student("张三", 89));
stuList.add(new Student("李四", 97));
stuList.add(new Student("王五", 60));
//方法一
// stuList.sort(new Comparator<Student>() {
//
// @Override
// public int compare(Student o1, Student o2) {
// // TODO Auto-generated method stub
//按成绩正序排序
// return o1.getGrade() - o2.getGrade();
//按成绩逆序排序
// return o2.getGrade() - o1.getGrade();
// }
//
// });
// System.out.println(stuList);
//方法二
Collections.sort(stuList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
return o2.getGrade() - o1.getGrade();
}});
System.out.println(stuList);
}
}
<2.Comparable
Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况:
1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数
2、比较者等于被比较者,那么返回0
3、比较者小于被比较者,那么返回负整数
package com.rjxy.day16.Test3;
//直接在内部类实现排序
public class Student implements Comparable<Student> {
private String name;
private int grade;
public Student(String name, int grade) {
this.name = name;
this.grade = grade;
}
@Override
public String toString() {
return "Student [name=" + name + ", grade=" + grade + "]";
}
//在该方法内完成排序
@Override
public int compareTo(Student o) {
return this.grade - o.grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
package com.rjxy.day16.Test3;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Student> stuList = new ArrayList<>();
stuList.add(new Student("张三", 89));
stuList.add(new Student("李四", 97));
stuList.add(new Student("王五", 60));
System.out.println("直接在Student方法内完成排序:");
Collections.sort(stuList);
System.out.println(stuList);
//[Student [name=王五, grade=60], Student [name=张三, grade=89], Student [name=李四, grade=97]]
}
}
重要!!!重要!!!重要!!!
🔺🔺🔺自定义实现ArrayList底层(仅可以接收String类型)
package com.rjxy.day16.Test4;
import java.util.Arrays;
/**
* 实现ArrayList
MyArray (String)
int size;//表示集合的元素个数
String[] strArray;
1.定义无参的构造方法 默认给数组10个
MyArray()
2.定义一个带参的构造方法
MyArray(int length);
3.add(String str);
判断元素的个数和数组的长度之间的关系 size>=strArray 扩容
添加元素
size++;
4.定义grow方法
规则:数组长度的一半(如果数组长度为1 ,扩容应该是+1)
5.add(int index,String str)
判断元素的个数和数组的长度之间的关系 size>=strArray 扩容
当前的数组元素后移
插入元素
size++;
6.remove(int index)
当前的数组元素前移
size--;
7.set(int index,String str):修改
8.get(int index):获取元素
9.size():返回集合中的元素个数
* @author 陶沅玱
*
*/
public class StrArrayList {
//表示集合中的元素个数
private int size;
//定义一个数组
private String[] strArray;
public StrArrayList() {
//默认给数组初始值10
strArray = new String[10];
}
//可以自己定义数组的长度
public StrArrayList(int length) {
strArray = new String[length];
}
//添加元素
public void add(String str) {
//ArrayList的扩容因子是1,即元素满了,收到下一个元素再扩容
if(size >= strArray.length) {
//扩容
grow();
}
//存储数据到最后一位,size的初始值为0
strArray[size] = str;
size++;
}
//进行数组的扩容
//ArrayList的扩容规则:数组长度的一半
public void grow() {
if(strArray.length <= 1) {
// 要扩容的目标数组 长度
Arrays.copyOf(strArray, strArray.length + 1);
}
Arrays.copyOf(strArray, (strArray.length + strArray.length/2));
}
//指定位置插入元素
public void add(int index, String str) {
if(size >= strArray.length) {
grow();
}
//{1,4,7,9} 插入位置:1 需要右移的元素个数:3
//{1, , 4,7,9} 4-1 = 3
//实现数组的拷贝
System.arraycopy(strArray, index, strArray, index+1, size-index);
strArray[index] = str;
size++;
}
//删除指定位置的元素
public void remove(int index) {
if(index >= size) {
try {
throw new Exception("下标异常");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//{1,4,5,6} 删除位置:1 需要左移的元素个数:2
//{1,5,6} 4-1-1=2
//实现数组的拷贝
System.arraycopy(strArray, index+1, strArray, index, size-1-index);
size--;
}
//修改指定位置的元素内容
public void set(int index, String str) {
strArray[index] = str;
}
//获取指定位置的元素
public String get(int index) {
return strArray[index];
}
//获取集合中元素的个数
public int size() {
return size;
}
}
package com.rjxy.day16.Test4;
public class Test {
public static void main(String[] args) {
StrArrayList a = new StrArrayList(4);
a.add("hello");
a.add("java");
for(int i=0; i<a.size(); i++) {
System.out.print(a.get(i) + "\t"); //hello java
}
System.out.println();
a.add(0, "hhhhh");
a.add(1, "ggggg");
for(int i=0; i<a.size(); i++) {
System.out.print(a.get(i) + "\t"); //hhhhh ggggg hello java
}
System.out.println();
a.remove(0);
for(int i=0; i<a.size(); i++) {
System.out.print(a.get(i) + "\t"); //ggggg hello java
}
System.out.println();
System.out.println(a.size()); //3
}
}