java進階筆記Day(六)
技術標籤:java進階筆記
Set集合
HashSet集合
HashSet集合保證元素唯一性的原理
HashSet底層資料結構是雜湊表結構,當往HashSet集合中儲存元素的時候
1.會計算元素的hashCode值,如果集合中已經有相同的hashCode值那麼還會判斷元素的equals是否相同
2.如果元素的equals比較也相同,那麼就認為元素重複;否則就不重複。
HashSet儲存自定義的元素
如果往HashSet集合中儲存自定義的物件,為了保證元素的唯一性,我們可以複寫hashCode和equals方法
public class Student {
private String name;
//構造法方法、get和set方法,此處省略(需要的話自己補充)
//複寫hashCode方法,讓hashCode值和物件的屬性值產生關聯;只要屬性值一樣,hashCode值就一樣 @Override public int hashCode() { return Objects.hash(name, age); } //複寫equals方法,讓equals方法的比較方式也和屬性值產生關聯;只要屬性值一樣,equals比較結果就相同 @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 && Objects.equals(name, student.name); }
}
LinkedHashSet
LinkedHashSet底層資料結構是:連結串列+雜湊表,可以保證元素的迭代順序
【HashSet和LinkedHashSet,除了迭代順序不一樣,其他的特點都是一樣的】
TreeSet集合
TreeSet集合可以對集合中的元素進行排序(可以是自然排序也可以是自定義排序),也可以保證元素唯一.
自然排序
1.元素實現Comparable介面
2.複寫compareTo方法,通過該方法的返回值是正數、負數、或者0來判斷元素是大、小、還是相等
正數:我們新增的元素比集合中已有的元素大
負數:我們新增的元素比集合中已有的元素小
零 : 我們新增的元素和集合中已有的元素相等(不儲存該元素)
private String name;
private int age;
//此處省略了構造方法、get和set方法、以及toString方法
@Override
public int compareTo(Student o) {
//按照學生的年齡進行排序
int num= this.age-o.age;
//如果年齡相同,就按照姓名的升序進行排列
if(num==0){
num=this.name.compareTo(o.name);
}
return num;
}
}
public class Demo3 {
public static void main(String[] args) {
TreeSet ts2=new TreeSet<>();
ts2.add(new Student(“xiaoming”,20));
ts2.add(new Student(“xiaoqiang”,30));
ts2.add(new Student(“xiaohuang”,28));
ts2.add(new Student(“xiaobai”,28));
for (Student stu : ts2) {
System.out.println(stu);
}
}
}
比較器排序
1.寫一個Comparator介面的實現類
2.複寫compare方法,通過該方法的返回值是正數、負數、或者0來判斷元素是大、小、還是相等
正數:我們新增的元素比集合中已有的元素大
負數:我們新增的元素比集合中已有的元素小
零 : 我們新增的元素和集合中已有的元素相等(不儲存該元素)
3.Comparator介面的實現類物件,當做TreeSet構造方法的引數
4.再往TreeSet集合中新增物件,該集合就可以對元素進行排序
//1.寫一個Comparator介面的實現類
//2.複寫compare方法,通過該方法的返回值是正數、負數、或者0來判斷元素是大、小、還是相等
public class MyComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
//首先按照學生的年齡升序進行排序
int num=o1.getAge()-o2.getAge();
//如果年齡相同,就按照姓名進行排序
if(num0){
num=o1.getName().compareTo(o2.getName());
}
return num;
}
}
public class Demo3 {
public static void main(String[] args) {
//3.Comparator介面的實現類物件,當做TreeSet構造方法的引數
//TreeSet ts=new TreeSet<>(new MyComparator());
TreeSet ts=new TreeSet<>(new Comparator() {
@Override
public int compare(Student o1, Student o2) {
//首先按照學生的年齡升序進行排序
int num=o1.getAge()-o2.getAge();
//如果年齡相同,就按照姓名進行排序
if(num0){
num=o1.getName().compareTo(o2.getName());
}
return num;
}
});
//4.再往TreeSet集合中新增物件,該集合就可以對元素進行排序
ts.add(new Student("xiaoming",18));
ts.add(new Student("xiaoqing",20));
ts.add(new Student("xiaoxing",19));
ts.add(new Student("xiaoding",18));
for (Student t : ts) {
System.out.println(t);
}
}
}
泛型
泛型表示一個不確定的資料型別,使用<字母>表示,比、<W,R>
泛型的好處
1.把執行時期的錯誤轉移到了編譯時期
- 在執行時有可能產生型別轉換的異常
2.避免了強制轉換的麻煩 - 使用泛型之後型別就統一了,自然就不會有型別轉換
泛型類
//在類名後面寫上一個<字母>,表示在類中有不確定的資料型別
public class GenericClass{
private T name;
public T getName(){
retur name;
}
public void setName(T name){
this.name=name;
}
}
//在建立物件的時候,來確定類上的泛型
public class GenericDemo1{
public static void main(String[] args){
//指定GenericClass類中的為String型別
GenericClass gc=new GenericClass();
gc.setName(“小明”);
String name=gc.getName();
System.out.println(name); //小明
System.out.println("----------");
//指定GenericClass類中的<T>為Integer型別
GenericClass<Integer> gc=new GenericClass<Integer>();
gc.setName(100);
Intger name=gc.getName();
System.out.println(name); //100
}
}
泛型方法
//在定義方法的時候,在返回值型別和修飾符之間寫一個<字母>,表示在方法中有一個不明確的資料型別
public void method(T t){
…
}
//呼叫泛型方法,通過實際引數來明確具體是什麼型別
method(“hello”);
method(100);
method(true);
泛型介面
//在定義介面時,在介面名的後寫一個<字母>,表示在介面中一個不明確的資料型別
public interface Inter{
public void method(T t){
…
}
}
//在Inter介面的實現類中來明確的資料型別
public class InterImpl implements Inter{
public void method(String t){
…
}
}
//把Inter介面中的泛型,沿用到實現類中,在建立實現類物件時來明確的實際型別
public class InterImpl implements Inter{
public void method(T t){
…
}
}
型別萬用字元
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
System.out.println(obj);
}
}
//引數是List集合,集合中元素可必須是Number或者Number的子類
public static void method2(List<? extends Number> list){
for (int i = 0; i < list.size(); i++) {
Number number = list.get(i);
System.out.println(number);
}
}
//引數是List集合,集合中元素可必須是Number或者Number的父類
public static void method3(List<? super Number> list){
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
System.out.println(obj);
}
}
可變引數
//可變引數:多個同類型的引數,本質上就是一個數組
//格式: 資料型別…變數名
public static int getSum(int…arr){
int sum=0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
public static void main(String[] args) {
int sum = getSum(3, 4);
System.out.println(sum); //7
int sum1 = getSum(3, 4, 5,113,40,5,5,6,6);
System.out.println(sum1); //12
int[] array={1,2,3,4,5,6};
int sum2 = getSum(array);
System.out.println(sum2);
}