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

34 篇文章 1 订阅

目录:

集合(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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public 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);
    }

    @Override
    public 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 {

    @Test
    public 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")));//true
        System.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());//2
        System.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 {
    @Test
    public 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;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }

    @Override
    public 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;
    }

    @Override
    public 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 {
    @Test
    public 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排序
    @Test
    public 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());
        }

        //定制排序,按照生日顺序进行排序
        @Test
    public void test2(){
            TreeSet set =new TreeSet(new Comparator() {
                @Override
                public 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());
        }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值