Comparable比较器写法&ClassCastExcption类转换异常

集合类图,如下所示

 

list集合

遍历方式:下标,forEach,迭代器(小编推荐使用)

初始化

List<Integer> list = new ArrayList<>();
    //初始化
    @Before
    public void setup() {
        list.add(1);
        list.add(3);
        list.add(3);
        list.add(4);
        list.add(2);
    }

结果:[1,3,3,4,2]

@Test
    //迭代器遍历
    public void test03() {
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

list集合怎么删除元素??

@Test
    //最好用迭代器删除,不易出错
    public void test04() {
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            if(iterator.next()==3) {
                iterator.remove();
            }
        }
        System.out.println(list);
    }

注意事项:

结果:[1,3, 2]

  @Test
    public void test05() {
        list.remove(3);
        list.remove(Integer.valueOf(3));
        System.out.println(list);
    }

list.remove(3);删除的是指定下标;

list.remove(Integer.valueOf(3));删除的一个指定的对象;

实现目标:[1,4,2]

结果:[1,3,4,2]

@Test
    public void test01() {
        for (int i = 0; i < list.size(); i++) {
            if(list.get(i)==3) {
                list.remove(i);
            }
        }
        System.out.println(list);
    }

解决方案

@Test
    public void test01() {
        for (int i = 0; i < list.size(); i++) {
            if(list.get(i)==3) {
                list.remove(i--);
            }
        }
        System.out.println(list);
    }

小编经验:当找到为第一个3(下标1)的下标时,删除之后,第一个3就为空了;第二个3(下标2)往前挤了一个下标,变成了(下标1)

Arraylist的一些特性:

  • 简单数据结构,超出容量自动扩容,动态数组

  • 内部实现是基于基础的对象数组的

  • 随机访问快

  • 不适合随机增加或删除

  • 线程不安全

LinkedList的一些特性:

  • LinkedList可被用作堆栈(stack)【包括了push,pop方法】,队列(queue)或双向队(deque)

  • Vector:线程安全(单独使用线程,等它使用完别人才能使用),性能慢。

CopyOnWriteArrayList的一些特性:

写的时候复制,完成所有操作后,将已经操作完成的数据直接给array,保持了最终一致性。

Set集合

遍历方式:forEach,迭代器

特点:无序,不重复

HashSet集合

它存储唯一元素并允许空值,不保持插入顺序

下面是去重例子

结果:[1,2,3]

初始化

private List<Integer> list = new ArrayList<>();
​
private Set<Integer> set=new HashSet<Integer>();
@Before
public void satrt() {
    list.add(1);
    list.add(2);
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(3);
    
    set.add(1);
    set.add(1);
    set.add(2);
    set.add(3);
    set.add(3);
    set.add(2);
}
@Test
    public void test01() {
        List<Integer> sa=new ArrayList<>(new HashSet<Integer>(list));
        System.out.println(sa);//给list去重
    }
    
@Test
    public void test02() {
        for(Integer e: set) {
            System.out.println(e);
        }
    }   

TreeSet集合

  1. 是一个包含有序的且没有重复元素的集合,作用是提供有序的Set集合

  2. 自然排序或者根据提供的Comparator进行排序

  3. TreeSet集合与HashSet的区别,插入结果是否进行排序。

error错误类型转换异常:

ClassCastExcption类转换异常,stu.add(new Student(1, "zs", 12))添加不进去。

解决方法:实现Comparable(比较器),然后重写比较器的方法即可。

按年龄排序结果如下

Student [sid=7, sname=lihao, age=1]
Student [sid=4, sname=lihao, age=10]
Student [sid=1, sname=zs, age=12]
Student [sid=2, sname=ls, age=19]
Student [sid=5, sname=zengfanyan, age=20]
Student [sid=3, sname=we, age=30]

Test

@Test
    public void test04() {
        Set<Student> stu = new TreeSet<Student>();
​
        stu.add(new Student(1, "zs", 12));
        stu.add(new Student(2,"ls", 19));
        stu.add(new Student(4,"lihao", 10));
        stu.add(new Student(7,"lihao", 1));
        stu.add(new Student(5,"zengfanyan", 20));
        stu.add(new Student(3,"we", 30));
        
        for(Student s: stu) {
            System.out.println(s);
        }
    }

Student实体必须实现Comparable(比较器)

比较者大于被比较者 返回1

比较者等于被比较者 返回0

比较者小于被比较者 返回-1

写法一
public class Student implements Comparable<Student>{
    @Override
    public int compareTo(Student o) {
        if(this.getAge()-o.getAge()==0) {
            return this.getSid()-o.getSid();
        }
        return this.getAge()-o.getAge();
    }
写法二
public class Student implements Comparable<Student>{
    @Override
    public int compareTo(Student o) {
        if(this.getSid()>o.getSid()) {
            return 1;
        }else{
            if(this.getSid()==o.getSid()) {
            return 0;
        }else{
        if(this.getSid()<o.getSid()){
            return -1;
         }
    }
}

上面代码与这个代码一样的

写法三
return this.getAge()-o.getAge();

Map集合

特点:无序,键值对现实存在,键不能重复,值可以重复

如果键重复则覆盖,没有继承Collection接口

遍历方式

初始化

Map<String, String> map=new TreeMap<>();
@Before
public void satrtUp() {
    map.put("1", "lkf");
    map.put("2", "zs");
    map.put("3", "ls");
    map.put("4", "wu");
    map.put("5", "ll");
}

通过keySet遍历

先获取所有键的Set集合,再遍历(通过键获取值)

结果:[lkf,zs,ls,wu,ll]

/**
     * 获取HashMap集合上的键的集合,保存ketSet集合里,然后使用ketSet集合自己的迭代器遍历
     */
    @Test
    public void test01() {
        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            String Key = iterator.next();
            System.out.println(map.get(Key));
        }
    } 

通过entrySet遍历

取出保存所有Entry的Set,再遍历此Set即可

结果:[1:kk,2:yy,3:zz]

@Test
	public void test02() {
		Map<String, String> maps=new HashMap<>();
		maps.put("1", "kk");
		maps.put("2", "yy");
		maps.put("3", "zz");
		
		Iterator<Entry<String, String>> iterator = maps.entrySet().iterator();//通过enrty获取自身的迭代器
		while (iterator.hasNext()) {//hasNext()判断该迭代器有无元素
			Entry<String, String> next = iterator.next();//entrySet()可获取键和值,属于一个集合
			System.out.println(next.getKey()+":"+next.getValue());
		}
	}

如何对已存在的key为1的记录进行了覆盖???

原结果:[1:lkf,2:zs,3:ls,4:wu,5:ll]

现结果:[1:yyy,2:zs,3:ls,4:wu,5:ll]

@Test
	public void test06() {
		//对已存在的key为1的记录进行了覆盖
		map.put("1", "yyy");
		Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {//hasNext()判断该迭代器有无元素
			Entry<String, String> next = iterator.next();//entrySet()可获取键和值,一个集合
			System.out.println(next.getKey()+":"+next.getValue());
		}
	}

HashMap集合

特点:线程不安全,最常用,速度快

基本原理:内部采用数组来存放数据

红黑树结果示图

 

红黑树怎么查找数据的?

通过数组下标,先找到指定下标的元素比较大小;如果比上一个元素下标大,就继续往下找,该链条上下一个元素下标;直到找到比该元素小的下标为止。

链条查找元素一般的找靠right(右边)的元素

TreeMap集合

key值按一定的顺序排序,但是比HashMap慢;因为需求维护内部的红黑树,用于保证key值的顺序

Map<String, Student> tree=new TreeMap<String, Student>();
@Before
	public void satrtUp() {
		tree.put("1", new Student(1, "zs",11));
		tree.put("2", new Student(2,"sb",12));
		tree.put("3", new Student(3,"ljj",13));
		tree.put("4", new Student(4,"zyz",14));
		tree.put("5", new Student(5,"yyxq",15));
	}

结果如下:

1:Student [sid=1, sname=zs, age=11]

2:Student [sid=2, sname=sb, age=12]

3:Student [sid=3, sname=ljj, age=13]

4:Student [sid=4, sname=zyz, age=14]

5:Student [sid=5, sname=yyxq, age=15]
@Test
	public void demo01() {
	tree.forEach((key, val) -> System.out.println(key + ":" + val));
	}

linkedHashMap集合

LinkedHashMap是有序的,且默认为插入顺序;

使用环境:当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了

结果如下

1:Student [sid=1, sname=zs, age=11]

2:Student [sid=2, sname=sb, age=12]

3:Student [sid=3, sname=ljj, age=13]

4:Student [sid=4, sname=zyz, age=14]

5:Student [sid=5, sname=yyxq, age=15]
/**
	 * linkedHashMap遍历
	 */
	@Test
	public void demo02() {
		Map<String, String> link=new LinkedHashMap<>();
		Set<Entry<String,String>> entrySet = link.entrySet();//获取entrySet集合
		
		Iterator<Entry<String, String>> iterator = entrySet.iterator();//通过enrty获取自身的迭代器
		while (iterator.hasNext()) {
			Entry<String, String> next = iterator.next();//entrySet()可获取键和值,属于一个集合
			System.out.println(next.getKey()+":"+next.getValue());
		}
		
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值