(九)Java集合进阶1-单列集合Collection

目录

1.单列集合Collection

1.1集合遍历

1.2 list特有的方法

2.双列集合Map

3.Arrays操作数组工具类

4.lambda表达式


1.单列集合Collection

List系列特点:添加的元素是有序(存取顺序相同,不是排序)、值可重复、有索引

Set系列集合:添加的元素是无序、不重复(可用于去重)、无索引

 public static void main(String[] args) {
        Collection<String> coll = new ArrayList<>();  //多态创建对象
        coll.add("A");
        coll.add("B");
        coll.add("C");
        System.out.println(coll);
    }
//输出为[A, B, C]

在 Java 中,Collection接口的很多实现类(如ArrayList)都重写了Object类的toString()方法。

当你使用System.out.println(coll)时,实际上调用的是coll这个集合对象的toString()方法。这个重写后的toString()方法会遍历集合中的元素,并以特定的格式(如[元素1, 元素2,...])返回集合的内容字符串,而不是默认的对象地址值。

如果没有重写toString()方法,那么打印对象时会输出对象的内存地址值,类似java.util.ArrayList@hashCode这样的形式。

public static void main(String[] args) {
        Collection<girlFriend> coll = new ArrayList<>();
        girlFriend g1 = new girlFriend("1", 19, 1.68);
        girlFriend g2 = new girlFriend("2", 19, 1.70);
        girlFriend g3 = new girlFriend("3", 18, 1.78);
        coll.add(g1);
        coll.add(g2);
        coll.add(g3);
        girlFriend g4 = new girlFriend("3", 18, 1.78);
        System.out.println(coll.contains(g4)); //false
    }

因为contains方法在底层依赖equals方法判对象是否一致的。如果存的是自定义对象,没有重写equals方法,那么默认使用object类中的equals方法进行判断,而object类中equals方法,依赖地址值进行判断,比较String类型不用重写equals是因为Java已经重写好了。

1.1集合遍历

由于普通for循环的遍历方式是基于索引的,但是set类型的是没有索引的,所以需要其他通用遍历方式,有三种:

  • 迭代器遍历
  • 增强for遍历
  • Lambda表达式遍历

public static void main(String[] args) {
        Collection<girlFriend> coll = new ArrayList<>();
        girlFriend g1 = new girlFriend("1", 19, 1.68);
        girlFriend g2 = new girlFriend("2", 19, 1.70);
        girlFriend g3 = new girlFriend("3", 18, 1.78);
        coll.add(g1);
        coll.add(g2);
        coll.add(g3);
        Iterator it = coll.iterator();  //创建指针
        while (it.hasNext()) {  //判断当前位置是否有元素
            girlFriend g5 = it.next();  //获取元素并移动指针
            System.out.println(g5);
        }
    }
//输出为:
//1 19 1.68
//2 19 1.7
//3 18 1.78

迭代器遍历注意事项:

  • 指针指向最后仍然it.next()的话会报错NoSuchElementException
  • 迭代器遍历完毕,指针不会复位
  • 循环中只能用一次next方法迭代器,不然会在一次循环中出现报错NoSuchElementException
  • 遍历时(while循环里),不能用集合的方法进行增加或删除,应该用迭代器的it.remove()方法或者创建列表迭代器ListItertor,调用它的add方法

增强for循环遍历

  • 增强for的底层就是迭代器,为了简化迭代器的代码书写的
  • 它是JDK5之后出现的,其内部原理就是一个Iterator迭代器
  • 所有的单列集合和数组才能用增强for进行遍历
    for(String s : list) {
        System.out.println(s);
    }

lambda表达式遍历

得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式

//匿名内部类格式
coll.forEach(new Consumer<String>() {

            @Override
            public void accept(String s) {
                System.out.println();
            }
        });
//lambda表达式
coll.forEach(s -> System.out.println(s));

1.2 list特有的方法

由于list相比于set多了索引的特点,所以多了一些索引相关的方法,比如list.remove(1);优先是删除索引为1的元素,为什么呢?

因为在调用方法的时候,如果方法出现了重载现象,优先调用实参跟形参类型一致的那个方法。list.remove(1)中的1默认是基本数据类型int,所以优先调用remove(int i)方法,想要删除值为1的元素需要手动装箱。

Integer i = Integer.valueOf(1);
list.remove(i);

2.双列集合Map

  • 双列集合一次需要存一对数据,分别为键和值
  • 键不能重复,值可以重复
    键和值是一一对应的,每一个键只能找到自己对应的值
  • 键+值这个整体 我们称之为“键值对”或者“键值对对象”,在Java中叫做“Entry对象”

3.Arrays操作数组工具类

public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        String s = Arrays.toString(arr);
        System.out.println(s);
        int a = Arrays.binarySearch(arr, 3);
        System.out.println(a);
        Integer[] arr2 = {2, 1, 3, 6, 5, 7, 8, 10, 4, 9}; 
        Arrays.sort(arr2);  //默认为升序排序
        System.out.println(Arrays.toString(arr2));
        Arrays.sort(arr2, new Comparator<Integer>() {  //匿名内部类,重写接口方法改为降序
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;  //o1 - o2升序;o2 - o1降序
            }
        });
        System.out.println(Arrays.toString(arr2));
    }
    //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    //2
    //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    //[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

如果要使用Arrays.toString方法转换对象类型,需要重写toString方法,例如有一个girlFriend的Javabean类,像下面这样直接调用Arrays.toString()方法打印的是girlFriend[]数组中g1, g2, g3三个对象的地址值。

public static void main(String[] args) {
        girlFriend g1 = new girlFriend("1", 19, 1.68);
        girlFriend g2 = new girlFriend("2", 19, 1.70);
        girlFriend g3 = new girlFriend("3", 18, 1.78);

        girlFriend[] arr = {g1, g2, g3};

       Arrays.sort(arr, (girlFriend o1, girlFriend o2)->{
                double temp = o1.getAge() - o2.getAge();
                temp = temp == 0 ? o1.getHeight() - o2.getHeight() : temp;
                if(temp > 0){
                    return 1;
                }else if(temp < 0){
                    return -1;
                }else {
                    return 0;
                }

        });
        System.out.println(Arrays.toString(arr));
    }
class girlFriend{
    @Override
    public String toString() {
        return this.name + " " + this.age + " " + this.height;
    }
} 
//在Javabean类中重写toString()方法再次调用输出为
//[3 18 1.78, 1 19 1.68, 2 19 1.7]

4.lambda表达式

在上面我们用匿名内部类实现接口,但是我们觉得这个写法太复杂了,所以发明了lambda表达式来简化匿名内部类的书写,Lambda表达式是JDK 8开始后的一种新语法形式,注意:

  • Lambda表达式可以用来简化匿名内部类的书写
  • Lambda表达式只能简化函数式接口的匿名内部类的写法
  • 函数式接口:有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@Functionalinterface注解
public static void main(String[] args) {
        Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        Arrays.sort(arr, new Comparator<Integer>() {  //匿名内部类,重写接口方法改为降序
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;  //o1 - o2升序;o2 - o1降序
            }
        });
        //lambda表达式,把多余的部分都省略
        Arrays.sort(arr, (Integer o1, Integer o2)->{
                return o2 - o1;
        });
        //lambda表达式省略写法,大量简化代码
        Arrays.sort(arr, (o1, o2)->o2 - o1);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值