当前位置: 代码迷 >> 综合 >> 不是太细的java自学笔记进阶篇4(p514-547)(集合Collection,iterator,foreach,set,TreeSet)
  详细解决方案

不是太细的java自学笔记进阶篇4(p514-547)(集合Collection,iterator,foreach,set,TreeSet)

热度:60   发布时间:2023-12-17 14:08:20.0

目录:

集合(List)

Collection API测试

数组和集合之间的相互转换

Iterator

foreach(内部使用的是迭代器)

ArrayList,LinkedList,Vector异同

List接口的常用方法:

set接口

set添加元素过程:(HashSet为例)

LinkedHashSet

TreeSet(底层为红黑树)


 

集合(List)

和数组一样对多个数据进行存储。

  

Map用来存储一对一对(key-value)的数据,类似高中的函数y=f(x),

 

Collection API测试

 

数组和集合之间的相互转换

数组到集合:Arrays.asList(T ... t)

集合到数组:toArray()

package com.lzy.collectionlearn;import java.util.Objects;/*** @author: lzy* @description: Person类* @date: 2020-09-14-15:01*/
public class Person {private String name;private  int age;Person(){}public Person(String name, int age){name=name;age=age;}public String getName() {return name;}public int getAge() {return age;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
package com.lzy.collectionlearn;
import org.junit.Test;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;/*** @author: lzy* @description: 用来测试Collection中接口的方法* @date: 2020-09-14-11:10*/
public class CollectionTest {@Testpublic void test1(){Collection coll=new ArrayList();//这个地方就是多态//添加元素e到集合中coll.add("aa");coll.add(123);//自动装箱//获取元素个数System.out.println(coll.size());//addAll()Collection coll1=new ArrayList();coll1.add("bb");coll1.add("cc");coll.addAll(coll1);System.out.println(coll.isEmpty());coll1.clear();coll.add(new String("Tom"));coll.add(new Person("ni",20));//可以放入自定义类boolean contains1=coll.contains(123);System.out.println(contains1);System.out.println(coll.contains(new String("Tom")));//trueSystem.out.println(coll.contains(new Person("ni",20)));//false,如果重写equals方法就可以成为true,如果不重写就是Object的equals()//containsAll(Collection coll2)判断是否coll1都在coll中Collection coll2= Arrays.asList(123,4567);System.out.println(coll.containsAll(coll2));coll.remove(123);//删除coll1中的coll2的所有元素。coll1.removeAll(coll2);//获取交集。coll1.retainAll(coll2);//完全相同返回true,包括顺序也要相同。coll.equals(coll2);//hashCode()返回当前对象的哈希值System.out.println(coll.hashCode());//集合-->数组Object[] arr=coll.toArray();for (int i=0;i<arr.length;i++){System.out.println(arr[i]);}//数组-->集合List<String> strings = Arrays.asList(new String[]{"aa", "bb", "cc"});System.out.println(strings);List arr1=Arrays.asList(new int[]{123,456});System.out.println(arr1.size());//1,通过下面的输出可以看出,系统把整个arr1当做了一个整体,而不是单独的两个System.out.println("==============================");System.out.println(arr1);//  [[I@4f2410ac]List arr2=Arrays.asList(new Integer[]{123,456});System.out.println(arr2.size());//2System.out.println(arr2);// [123, 456]//iterator迭代器接口,用于集合元素的遍历}
}

需要注意的是:在下图第二种方法中如果 new一个int类型的数组是没法存入数组中的属性的,只能把这个数组作为衣蛾整体存入到集合中。需要转换成Integer包装类才行。

第二:正常来说我们直接加Arrays.asList({..........})即可,这样可以避免数据的类型·错误。

 

Iterator

 

一般来说使用iterator.hasNext()函数来判断是否遍历完成。

错误举例:

 

错误方式1会造成跳着输出,并且最后会导致抛出异常

错误方式2会造成一直输出第一个。无限循环。

 

iterator.remove()移除某一个数据。

但是在删除了一个数据之后不能再删除一次,需要next才能再删除。

package com.lzy.collectionlearn;import org.junit.Test;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*** @author: lzy* @description: Iterator联系* @date: 2020-09-14-15:43*/
public class IteratorTest {@Testpublic void test1(){Collection coll=new ArrayList();coll.add(123);coll.add(456);coll.add(new Person("Jerry",11));coll.add(new String("nihao"));coll.add(false);Iterator iterator = coll.iterator();System.out.println(iterator);//指向的是这个集合的地址System.out.println(iterator.next());//第一个元素while(iterator.hasNext())// 常用的方法,用来遍历,遍历前判断了是否还要下一个值{System.out.println(iterator.next());}}
}

 

 

foreach(内部使用的是迭代器)

可以遍历集合和数组。

 

注意如果修改obj,是不会改变本身的集合元素。改变的是局部变量。

 

ArrayList,LinkedList,Vector异同

同:都是作为List接口的实现类,都是有序的可重复的数据。

不同:ArrayList:作为List接口的主要实现类,线程不安全的的,效率高,底层使用数组实现

   Vector:作为List接口的古老实现类,线程安全的,效率低。使用数组实现

   LinkedList:底层使用双向链表存储。

 

    jdk8.0中(7类似饿汉式。8类似懒汉式,延迟了数组创建)

在定义了实例后底层并没创建一个有长度的数组,只有在第一次add之后才真正创建一个有长度的数组,后续的添加和扩容中的操作和jdk7无异。

List接口的常用方法:

  

set接口

   

set中没有新定义的方法,不像list中有索引需要自定义犯法。

set底层实现同样是使用的数组方式。

set的无序性:并非是随机性的,存储的数据在底层的数组中不是按照从头到尾的顺序进行添加,而是按照哈希算法添加。

set的不可重复性:添加的元素按照equals()方法判断时,不能返回true。即:相同的元素只能添加一个。

set添加元素过程:(HashSet为例)

 

JDK7,把原来的元素放到链表上,JDK8把新加的元素放到链表上。

 

要求:1。向set中添加数据,其所在的类一定要重写hashCode(),equals()方法,并且重写的两个方法要保持一致性。(用来保证:相等的对象具有相等的散列码)

 

LinkedHashSet

作为HashSet的子类,添加方法在原来的基础上增加了头尾指针,实现了按照添加顺序顺序遍历的功能,但是本身在底层存放的是无序的(按照上HashSet),对于频繁的便利操作,效率更高。

TreeSet(底层为红黑树)

向TreeSet中添加的数据,要求是相同类的对象,不可以添加不同类的对象。(例如只能添加Integer类型或者Boolean或者自定义类)

在TreeSet中比较本身就是使用的compareTo方法比较。所以当比较结果是0就会当做相同。不再是上面方法的equals()。

并且自动排序按照从小到大顺序排列。

但是自定义类中需要重写排序方法也就是之前讲过的(comparable和compareTo,位于章节比较器)

 

自然排序举例(代码在最后):

   

定制排序举例:

  

例2:

 

如果不添加参数也就是com,会按照默认方式进行排序,如果添加参数就会按照参数方式进行排序。(注意按照上述代码方式进行排序,如果出现相同的年龄时,会出现其他相同的年龄内容消失,因为只比较年龄导致了compareTo方式比较结果为0.这个时候就会出现系统认为两者相同的情况,即使name不相同也不会判断为不相同对象。如果要修复这个问题需要修改比较方式。)

 

set,TreeSet案例代码:(已经放入github->这个)

文件结构如下:

 以上文件代码如下所示:

Employee:

package com.lzy.setlearn;/*** @author: lzy* @description:* @date: 2020-09-16-14:27*/
public class Employee implements Comparable{private String name;private  int age;private MyDate birthday;public Employee(){}public Employee(String name, int age, MyDate birthday) {this.name = name;this.age = age;this.birthday = birthday;}public String getName() {return name;}public int getAge() {return age;}public MyDate getBirthday() {return birthday;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", age=" + age +", birthday=" + birthday +'}';}@Overridepublic int compareTo(Object o) {if (o instanceof Employee){Employee e=(Employee)o;return this.name.compareTo(e.name);}else{throw new RuntimeException("error");}}
}

MyDate:

package com.lzy.setlearn;/*** @author: lzy* @description:* @date: 2020-09-16-14:26*/
public class MyDate {private int year;private int month;private int day;public MyDate() {}public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}public int getYear() {return year;}public int getMonth() {return month;}public int getDay() {return day;}public void setYear(int year) {this.year = year;}public void setMonth(int month) {this.month = month;}public void setDay(int day) {this.day = day;}@Overridepublic String toString() {return "MyDate{" +"year=" + year +", month=" + month +", day=" + day +'}';}
}

SetLearn:

package com.lzy.setlearn;import com.lzy.collectionlearn.Person;
import org.junit.Test;import java.util.HashSet;
import java.util.Iterator;/*** @author: lzy* @description: 联系set接口** @date: 2020-09-16-10:44*/
public class SetLearn {@Testpublic void test1(){HashSet set = new HashSet();set.add(123);set.add(456);set.add("aa");set.add("cc");set.add(new Person("Tom",12));Iterator iter=set.iterator();while (iter.hasNext()){System.out.println(iter.next());}}
}

TreeSetTest:

package com.lzy.setlearn;import org.junit.Test;import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;/*** @author: lzy* @description: 写一个TreeSet例题* @date: 2020-09-16-14:31*/
public class TreeSetTest {//使用自然排序,使Employee实现全Comparable接口,并且按照name排序@Testpublic void test1(){TreeSet set =new TreeSet();Employee e1=new Employee("name1",1,new MyDate(1990,1,1));Employee e2=new Employee("name4",4,new MyDate(1923,3,23));Employee e3=new Employee("name3",3,new MyDate(1978,6,12));Employee e4=new Employee("name4",8,new MyDate(1998,3,18));Employee e5=new Employee("name5",23,new MyDate(1999,3,31));set.add(e1);set.add(e2);set.add(e3);set.add(e4);set.add(e5);//System.out.println(set);Iterator iterable=set.iterator();while(iterable.hasNext())System.out.println(iterable.next());}//定制排序,按照生日顺序进行排序@Testpublic void test2(){TreeSet set =new TreeSet(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {if(o1 instanceof Employee && o2 instanceof Employee){Employee e1=(Employee)o1;Employee e2=(Employee)o2;MyDate b1=e1.getBirthday();MyDate b2=e2.getBirthday();int sumYear=b1.getYear()-b2.getYear();int sumMonth=b1.getMonth()-b2.getMonth();System.out.println("*******");if(sumYear!=0)return sumYear;//是通过差值进行比较if(sumMonth!=0)return sumMonth;return b1.getDay()-b2.getDay();}throw new RuntimeException("error1");}});Employee e1=new Employee("name1",1,new MyDate(1990,1,1));Employee e2=new Employee("name4",4,new MyDate(1923,3,23));Employee e3=new Employee("name3",3,new MyDate(1978,6,12));Employee e4=new Employee("name4",8,new MyDate(1998,3,18));Employee e5=new Employee("name5",23,new MyDate(1999,3,31));set.add(e1);set.add(e2);set.add(e3);set.add(e4);set.add(e5);Iterator iterable=set.iterator();while(iterable.hasNext())System.out.println(iterable.next());}
}

 

  相关解决方案