本帖最后由 小石姐姐 于 2019-5-9 18:31 编辑
个人笔记一、Set集合概述和特点1.元素存取无序 2.没有索引 3.不能存储重复元素 二、哈希值概念是JDK根据对象的地址或字符串或数字计算出来的一串int类型的数值 如何获取哈希值Object类中有一个方法:hashCode()用于获取哈希值 三、HashSet集合概述和特点1.底层是哈希表结构 2.元素存取无序 3.没有索引 4.不能存储重复元素 四、HashSet集合保证元素唯一性源码分析HashSet集合保证元素唯一性的原理 add("aa");方法----hashCode()计算"aa"的hash值 1.根据对象的哈希值计算存储位置 如果当前位置没有元素则直接存入 (方法中的生成数组的存储位置) 如果当前位置有元素存在,则进入第二步 2.当前元素的元素和已经存在的元素比较哈希值 如果哈希值不同,则将当前元素进行存储 (以前的元素的链表的最后面) 如果哈希值相同,则进入第三步 3.通过equals()方法比较两个元素的内容 (和以前的元素的链表的每个元素内容进行比较) 如果内容不相同,则将当前元素进行存储(以前的元素的链表的最后面) 如果内容相同,则不存储当前元素 五、常见数据结构之哈希表六、HashSet集合存储学生对象并遍历
[Java] 纯文本查看 复制代码 package hashset;
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 +
'}';
}
//为了实现Set集合的特点。不能有重复的元素,需要重写equals()和hashCode()方法,自动生成即可
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
//为了让java虚拟机先去比较两个对象的hash值,用这个hashCode()方法获取hash值
//如果hash值相同,就去调用equals()方法,来比较两个对象的内容,如果不同,就存储
//相同则不存储,如果hash值不同,就直接存储这个对象
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
package hashset;
import java.util.HashSet;
public class HashSetTest {
public static void main(String[] args) {
//创建HashSet对象
HashSet<Student> hs = new HashSet<>();
//创建学生对象
Student s1 = new Student("张三",21);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",23);
Student s4 = new Student("王五",23);
//添加学生对象
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//增强for循环遍历集合
for (Student s : hs){
System.out.println(s);
}
}
}
七、LinkedHashSet集合概述和特点1.LinkedHashSet集合是HashSet集合的子类 2.LinkedHashSet集合不能存储重复元素 3.LinkedHashSet集合可以保证元素存取有序 总结特点:LinkedHashSet集合可以按照存储顺序来取出数据
[Java] 纯文本查看 复制代码 package linkedhashset;
//LingkedHashSet集合可以按照存储顺序来取出数据
import java.util.LinkedHashSet;
public class LinkedHashSetTest {
public static void main(String[] args) {
//创建LinkedHashSet集合对象
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
//添加元素
lhs.add("aaa");
lhs.add("bbb");
lhs.add("ccc");
//增强for循环输出
for (String s : lhs){
System.out.println(s);
}
}
}
八、TreeSet集合概述和特点1.元素有序。元素可以按照一定规则进行排序。具体要取决于构造方法 TreeSet():根据元素的自然顺序进行排序 TreeSet(Comparator c):根据指定的比较器进行排序 实现自然排序Comparable接口,来创建指定的自然排序 2.TreeSet集合没有索引。只能通过迭代器、增强for循环进行遍历 3.TreeSet集合不能存储重复元素 [Java] 纯文本查看 复制代码 package treeset;
/*
特点:
不能有重复元素
默认构造方法,按照jdk指定的自然排序,1-10,a-z...这样的顺序排序
*/
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
//创建TreeSet集合对象
TreeSet<String> treeSet = new TreeSet<>();
//添加元素
treeSet.add("ccc");
treeSet.add("ddd");
treeSet.add("aaa");
treeSet.add("bbb");
treeSet.add("段");
treeSet.add("孟");
treeSet.add("钊");
//增强for循环输出
for (String s : treeSet){
System.out.println(s);
}
}
}
九、自然排序Comparable的使用
[Java] 纯文本查看 复制代码 package comparable;
import java.io.Serializable;
public class Student implements Comparable<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 int compareTo(Student s) {
int num1 = this.age - s.age;
//string类中也重写了compareTo()方法
int num2 = num1 == 0 ? this.name.compareTo(s.name) : num1;
return num2;
}
}
package comparable;
import java.util.TreeSet;
public class ComparableTest {
public static void main(String[] args) {
//创建TreeSet集合对象:默认构造方法不能排序我们自己给定的自定义对象
//这是需要使用第一种方式:自然排序Comparable接口
/*
1.实现自然排序Comparable接口:Student implements Comparable<Student>
2.重写comprareTo()方法,返回值是int类型,返回值规则:
为0:代表两个相比较的对象是相等的,根据Set集合特性不能有重复元素,他是不会添加进集合中的
为正数1:代表后面添加进去的对象a比前面添加进去的对象b大,按照从小到大排序,a排在b的后面
为负数-1:代表后面添加进去的对象a比前面添加进去的对象b小,按照从大到小排序,a排在b的前面
*/
TreeSet<Student> ts = new TreeSet<>();
//按照年龄大小排序,从小到大,次级按照姓名排序,从小到大
Student s1 = new Student("张三",21);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",23);
Student s4 = new Student("赵六",23);//为了更好的排序
Student s5 = new Student("赵六",23);//为了显示Set集合的特点:不重复的元素
//添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
//增强for循环输出
for (Student s : ts){
System.out.println(s);
}
}
}
十、比较器排序Comparator的使用技巧:Comparator集合也是接口,但是我们只使用一次,建议使用匿名内部类调用
[HTML] 纯文本查看 复制代码 package comparable;
import java.io.Serializable;
public class Student implements Comparable<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 int compareTo(Student s) {
int num1 = this.age - s.age;
//string类中也重写了compareTo()方法
int num2 = num1 == 0 ? this.name.compareTo(s.name) : num1;
return num2;
}
}
package comparable;
import java.util.Comparator;
import java.util.TreeSet;
public class ComparatorTest {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//s1---this,s2---s
int num1 = s1.getAge() - s2.getAge();
//string类中也重写了compareTo()方法
int num2 = num1 == 0 ? s1.getName().compareTo(s2.getName()) : num1;
return num2;
}
});
Student s1 = new Student("张三",21);
Student s2 = new Student("李四",22);
Student s3 = new Student("王五",23);
Student s4 = new Student("赵六",23);//为了更好的排序
Student s5 = new Student("赵六",23);//为了显示Set集合的特点:不重复的元素
//添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
//增强for循环输出
for (Student s : ts){
System.out.println(s);
}
}
}
十一、成绩排序
[Java] 纯文本查看 复制代码 package comparator;
public class Student implements Comparable<Student> {
private String name;
private int chinese;
private int math;
public Student() {
}
public Student(String name, int chinese, int math) {
this.name = name;
this.chinese = chinese;
this.math = math;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", chinese=" + chinese +
", math=" + math +
", num=" + getSum() +
'}';
}
public int getSum(){
return chinese+math;
}
@Override
public int compareTo(Student s) {
/*
在compareTo()方法中,
this:代表当前添加的对象,
s:代表要进行比较的对象,
返回值:s.getSum() - this.getSum()
0---代表s.getSum()和this.getSum()相同,不会添加这个this.getSum()对象
正数1---代表this.getSum()这个对象要排在s.getSum()这个对象的前面,按从大到小排序
负数-1---代表this.getSum()这个对象要排在s.getSum()这个对象的后面,按从小到大排序
*/
//System.out.println(this.name);
//System.out.println(s.name);
int num1 = s.getSum() - this.getSum();
int num2 = num1 == 0 ? this.chinese - s.chinese : num1;
int num3 = num2 == 0 ? this.name.compareTo(s.name) : num2;
return num3;
}
}
package comparator;
/*
//使用自然排序comparable接口,
需要在需要排序的对象的自定义类中实现Comparable接口:implements Comparable<自定义类名>
这里传的参数是你要进行比较的对象的自定义类
并且要重写Comparable接口中的compareTo(自定义类名 引用名)方法,
*/
import java.util.TreeSet;
public class ComparableTest {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<>();
Student s1 = new Student("张三",65,85);
Student s2 = new Student("李四",70,85);
Student s3 = new Student("王五",80,85);
Student s4 = new Student("赵六",80,85);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s : ts){
System.out.println(s);
}
}
}
package comparator;
//按照学生成绩,从高到低进行排序
import java.util.Comparator;
import java.util.TreeSet;
public class ComparatorTest {
public static void main(String[] args) {
//使用比较器Comparator接口,只用一次,所以使用匿名内部类来实现Comparator接口
//
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
/*
new Comparator<自定义类名>(){这里传的参数是你要进行比较的对象的自定义类
匿名内部类需要重写Comparator接口的方法---compare(自定义类名 引用名)
注意:返回值:0--代表和集合已经存在的元素进行相比较的元素相同,不会存储到集合
正数1:---代表和集合已经存在的元素进行相比较的元素a,比已经存在的元素b大,
a会排在b的后面,按照从小到大排序
负数-1---代表和集合已经存在的元素进行相比较的元素a,比已经存在的元素b小,
a会排在b的前面,按照从大到小排序
}
*/
@Override
public int compare(Student s1, Student s2) {
int num1 = s2.getSum() - s1.getSum();
int num2 = num1 == 0 ? s1.getChinese() - s2.getChinese() : num1;
int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2;
return num3;
}
});
Student s1 = new Student("张三",65,85);
Student s2 = new Student("李四",70,85);
Student s3 = new Student("王五",80,85);
Student s4 = new Student("赵六",80,85);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student s : ts){
System.out.println(s);
}
}
}
十二、不重复的随机数
[Java] 纯文本查看 复制代码 package random;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
/*
1.创建一个HashSet和TreeSet集合对象,泛型为Integer类型
2.创建Random对象,用于生成随机数
3.使用while循环判断集合长度是否不等于10
如果长度不为10,则生成随机数保存到集合中
4.使用增强for循环遍历集合
*/
public class SetTest {
public static void main(String[] args) {
//创建一个HashSet对象,泛型为Integer类型
//Set<Integer> s = new HashSet<Integer>();//生成无序
Set<Integer> s = new TreeSet<Integer>();//生成有序
//创建Random对象,用于生成随机数
Random r =new Random();
//使用while循环判断集合长度是否不等于10
while(s.size() <= 10){
//添加随机数,生成1-20的随机数
int i = r.nextInt(20) + 1;
s.add(i);
}
//使用增强for循环遍历集合
for (Integer i : s){
System.out.println(i);
}
}
}
十三、泛型概述和好处什么是泛型(参数化类型) 泛型指的是广泛的数据类型,就是将原来具体的类型参数化,在使用的时候再传入具体的类型! 泛型的好处 (在编译期类型检查,不用类型转换)将运行时期的错误提前到了编译期间 省去了类型转换的麻烦 十四、泛型类
泛型类的定义(在自定义类名后面加<E e>,E,T,Y泛指所有类型)
[Java] 纯文本查看 复制代码 public class Generic<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
泛型类的使用
[Java] 纯文本查看 复制代码 Generic<String> g1 = new Generic<String>();
g1.setT("林青霞");
System.out.println(g1.getT());
Generic<Integer> g2 = new Generic<Integer>();
g2.setT(30);
System.out.println(g2.getT());
十五、泛型方法
泛型方法的定义(在修饰符后面加<E e>,E,T,Y泛指所有类型)
[Java] 纯文本查看 复制代码 public class Generic {
public <T> void show(T t) {
System.out.println(t);
}
}
泛型方法的使用
[Java] 纯文本查看 复制代码 Generic g = new Generic();
g.show("林青霞");
g.show(30);
g.show(true);
g.show(12.34);
十六、泛型接口
泛型接口的定义(在自定义类名后面加<E e>,E,T,Y泛指所有类型)
[Java] 纯文本查看 复制代码 public interface Generic<T> {
void show(T t);
}
public class GenericImpl<T> implements Generic<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
泛型接口的使用
[Java] 纯文本查看 复制代码 Generic<String> g1 = new GenericImpl<String>();
g1.show("林青霞");
Generic<Integer> g2 = new GenericImpl<Integer>();
g2.show(30);
十七、类型通配符<?>List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中类型通配符向上限定 <? extends 类型>List<? extends Number>:它表示的类型是Number或者其子类型类型通配符向下限定 <? super 类型> List<? super Number>:它表示的类型是Number或者其父类型 十八、可变参数什么是可变参数可变参数又称为参数个数可变,用于方法的形式参数使用。 可变参数的注意事项可变参数其实是一个数组 如果一个方法有多个参数,而且包含可变参数。可变参数要放在最后
[Java] 纯文本查看 复制代码 public static void main(String[] args) {
System.out.println(show(10,20));
System.out.println(show(10,20,30));
System.out.println(show(10,20,30,40));
}
/*public static void show(int a,int b){
System.out.println(a+", "+b);
}
public static void show(int a){
System.out.println(a+);
}
public static void show(int a,int b,int c){
System.out.println(a+", "+b+", "+c );
}*/
/*public static int show(int... a){
int sum = 0;
for (int i : a){
sum+=i;
}
return sum;
}*/
public static int show(int b, int...a){
int sum = 0;
for (int i : a){
sum+=i;
}
return sum;
}
十九、可变参数的使用
JDK中提供的类使用可变参数的方法
[Java] 纯文本查看 复制代码 Arrays工具类中有一个静态方法:
public static <T> List<T> asList•(T... a):返回由指定数组支持的固定大小的列表
List接口中有一个静态方法:
public static <E> List<E> of•(E... elements):返回包含任意数量元素的不可变列表
Set接口中有一个静态方法:
public static <E> Set<E> of•(E... elements) :返回一个包含任意数量元素的不可变集合
//public static <T> List<T> asList•(T... a):返回由指定数组支持的固定大小的列表
/*List<Integer> list = Arrays.asList(10,20,30);
//list.add(40);//UnsupportedOperationException,不能添加元素
//list.remove(20);//UnsupportedOperationException,不能删除元素
list.set(1,40);//可以修改元素
System.out.println(list);*/
//public static <E> List<E> of•(E... elements):返回包含任意数量元素的不可变列表
/*List<Integer> list = List.of(10,20,30);
//list.add(40);//UnsupportedOperationException,不能添加元素
//list.remove(20);//UnsupportedOperationException,不能删除元素
//list.set(1,40);//不能修改元素
System.out.println(list);*/
//public static <E> Set<E> of•(E... elements) :返回一个包含任意数量元素的不可变 集合
Set<Integer> set = Set.of(10,20,30);
//set.add(40);//UnsupportedOperationException,不能添加元素
//set.remove(20);//UnsupportedOperationException,不能删除元素
//set.set(1,40);//Set集合里面没有带索引的方法,例如:set()
System.out.println(set);
|