java学习笔记-数组和集合

拆箱装箱

在使用集合(如List, Set等)和泛型时,集合和泛型在Java中通常使用包装类而不是基本数据类型。

1.使用集合时:当你需要将基本数据类型存储在集合(如ArrayList, HashSet等)中时,由于集合是泛型的,它们只接受对象作为元素。因此,你需要将基本数据类型转换为对应的包装类。Java编译器会自动为你进行这种转换,即装箱。

从集合中检索值:当你从集合中检索一个包装类类型的值时,并尝试将其赋值给一个基本数据类型的变量时,会发生拆箱。

List<Integer> list = new ArrayList<>();  
list.add(5); // 这里的5被自动装箱为Integer.valueOf(5)
int num = list.get(0); // 这里的list.get(0)被自动拆箱为int值5

2.方法参数:当方法参数是包装类类型,而你传递了一个基本数据类型值时,会发生装箱。

方法返回值:当方法返回的是包装类类型,而你尝试将其赋值给一个基本数据类型的变量时,会发生拆箱。

//装箱
public void printInteger(Integer i) {  
    System.out.println(i);  
}  
  
printInteger(10); // 这里的10被自动装箱为Integer.valueOf(10)
																				
//拆箱
public Integer getNumber() {  
    return 10;  
}  
  
int num = getNumber(); // 这里的getNumber()返回值被自动拆箱为int值10

3.赋值给包装类类型的变量:当你将一个基本数据类型的值赋给一个包装类类型的变量时,会发生装箱。

进行算术运算:当你尝试对包装类类型的值进行算术运算时,它们会被自动拆箱为基本数据类型,以执行运算,然后再根据需要重新装箱。

Integer i = 10; // 这里的10被自动装箱为Integer.valueOf(10)
//自动装箱拆箱原理:基本数据类型和类类型数据之间的自动转化
        int a = 2;
        Integer b = a; //基本类型->类类型:装箱
        int c = b; //类类型->基本类型:拆箱
																			
Integer a = 10;  
Integer b = 5;  
int sum = a + b; // 这里的a和b被自动拆箱为int值,执行加法运算后再赋值给sum

集合和数组的区别

区别

1.数组必须指定长度,集合是动态长度

2.数组两种类型都可以存储(Integer\int),集合只能存储类类型(Integer)

3.数组中的元素可以通过索引来访问和修改,索引从0开始。

集合中的元素可以通过迭代器(Iterator)或增强的for循环(也称为"foreach"循环)来访问。修改集合中的元素则取决于集合的具体类型和实现。

4.数组在内存中分配的是一块连续的空间,这使得数组在访问元素时具有较高的效率。但是,这也使得在数组中间插入或删除元素时效率较低,因为可能需要移动其他元素以保持连续性。

集合在内存中的存储方式可能因实现而异。例如,ArrayList在内存中也是分配一块连续的空间,但LinkedList则使用链表结构,每个元素都保存了指向下一个元素的引用。这使得LinkedList在插入和删除元素时具有较高的效率,但在访问元素时效率较低。

        int[] intarray = new int[]{1,2,3,4};
        Integer[] array = new Integer[]{1,2,3,4};
        System.out.println(Arrays.toString(array)); //[1, 2, 3, 4]

        List<Integer> list = Arrays.asList(array); //将数组转为集合
        System.out.println(list); //[1, 2, 3, 4]

Arrays.asList()与List的区别

1.Arrays.asList()返回的List是一个固定长度的List,其底层数据结构是数组。而普通的List实现类(如ArrayList)底层通常采用数组或链表等数据结构。

2.Arrays.asList()返回的List是不可变的,即无法改变其长度。而普通的List实现类通常是可变的,可以根据需要动态改变长度。

3.由于Arrays.asList()返回的List是不可变的,因此对其进行增删操作会受到限制。而普通的List实现类提供了更多的操作方法,如add()、remove()、clear()等。

数组转为集合

什么情况下需要转?

你有一个数组,但你希望使用集合的特定方法(如排序、查找、去重等)。如果你有一个基本数据类型的数组,并且你想将其存储在一个泛型集合中(如List<Integer>),你需要将数组转换为包装类类型的集合。

Arrays.asList()方法是Java中Arrays类提供的一个静态方法,用于将数组转换为List集合。它接收一个数组作为参数,并返回一个包含数组元素的List集合。

        Integer[] array = new Integer[]{1,2,3,4};
        System.out.println(Arrays.toString(array)); //[1, 2, 3, 4]
        //当我们需要创建一个不需要改变大小或者内容的 List 集合时,我们可以使用 Arrays.asList() 来快速地初始化一些元素
        List<Integer> list = Arrays.asList(array); //将数组转为集合
        //list.add(2); 直接对list进行编辑会抛出异常UnsupportedOperationException
        System.out.println(list); //[1, 2, 3, 4]

使用Arrays.asList()方法转换的List是一个固定长度的List,它的长度与原始数组的长度相同。这意味着我们无法通过添加或删除元素来改变List的长度,否则会抛出UnsupportedOperationException异常。如果需要对List进行增删操作,可以考虑创建一个新的ArrayList并将转换后的List作为构造函数的参数。

        String[] array1 = {"apple", "banana", "orange"};
        List<String> stringList = new ArrayList<>(Arrays.asList(array1));
        stringList.add("grape"); // 可以对新创建的ArrayList进行增删操作

通过stream()方法将基本类型的数组转为集合

//stream
        Integer[] array2 ={11,22,33};
        List list1 = Arrays.stream(array2).collect(Collectors.toList());
        System.out.println(list1);

        //基本数据类型也可以实现转换(依赖boxed装箱操作)
        int[] array3 = {44,55,66};
        List list2 = Arrays.stream(array3).boxed().collect(Collectors.toList());
        System.out.println(list2);

set,list,map

//list是有序可重复的
        List<String> users = new LinkedList<String>();
        users.add("zhangsan");
        users.add("zhangsan");
        users.add("lisi");
        users.add("wangwu");
        System.out.println(users); //[zhangsan, zhangsan, lisi, wangwu]
        for (String user : users) {
            System.out.println(user);  //zhangsan zhangsan lisi wangwu
        }

        //set是无序不重复的
        Set<String> set = new HashSet<String>();
        set.add("zhangsan");
        set.add("zhangsan");
        set.add("zhangsan");
        set.add("李四");
        set.add("李四");
        for (String s:set
             ) {
            System.out.println(s); //李四 zhangsan
        }



        Map<String,String> map = new HashMap<String,String>();
        map.put("1","zhangsan");
        map.put("2","lisi");
        map.put("3","wangwu");
        System.out.println(map); //{1=zhangsan, 2=lisi, 3=wangwu}
        for (String m: map.keySet()
             ) {
            System.out.println(m); //1 2 3
            //System.out.println(map.get(m)); //zhangsan lisi wangwu
        }

ArrayList和LinkedList


        //ArrayList底层是数组,遍历快,添加删除慢
        //LinkedList底层是链表,遍历慢,添加删除快
        List<String> list3 = new LinkedList<>();
        list3.add("abc");
        list3.add("efg");
        for (String s:list3
             ) {
            System.out.println(s);
        }

TreeSet和HashSet

package com.training;

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class SetTraining {
    public static void main(String[] args) {
        //HashSet和TreeSet区别
        //两者都遵循 Set 接口的规范,即它们都不允许存储重复的元素。这是通过元素的 equals() 方法来确定的。
        //TreeSet不重复,排序,底层数据结构式一个二叉树,TreeSet 由于需要维护元素的排序,因此在插入、删除和查找元素时通常比 HashSet 慢
        Set<String> set = new TreeSet<String>();
        set.add("4");
        set.add("3");
        set.add("2");
        set.add("4");
        System.out.println(set.add("3"));//false 添加失败
        for (String s:set
             ) {
            System.out.println(s); //2 3 4
            System.out.println(s.hashCode());
        }
        System.out.println("-------------------------");
        //HashSet不重复,底层数据结构是哈希表,它在插入、删除和查找元素时通常比 TreeSet 更快
        Set<String> set1 = new HashSet<>();
        set1.add("4");
        set1.add("3");
        set1.add("2");
        set1.add("4");
        set1.add("3");
        System.out.println(set1.add("3"));//false 添加失败
        for (String s:set1
        ) {
            System.out.println(s); //2 3 4

        }
    }

}

HashMap、TreeMap、Hashtable

package com.training;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.TreeMap;

public class MapTraining {
    public static void main(String[] args) {
        // HashMap键值对实现,线程不安全
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "null");
        Sites.put(null, "Zhihu");
        // 输出 key 和 value
        for (Integer i : Sites.keySet()) {
            System.out.println("key: " + i + " value: " + Sites.get(i));//key: 1 value: Google
        }
        System.out.println("---------------------------");
        // 返回所有 value 值
        for(String value: Sites.values()) {
            // 输出每一个value
            System.out.print(value + ", ");//Zhihu, Google, Runoob, Taobao, null,
        }
        System.out.println("\n"+"---------------------------");
        System.out.print("set view:"+ Sites.entrySet());//set view:[null=Zhihu, 1=Google, 2=Runoob, 3=Taobao, 4=null]
        System.out.println("\n"+"---------------------------");
        for (Entry<Integer, String> entry: Sites.entrySet()
             ) {
            System.out.print(entry+ ", ");
        }


        System.out.println("\n"+"---------------------------");
        //TreeMap按照key进行排序,不允许使用null键,但允许使用null值。
        TreeMap<Integer, String> users = new TreeMap<>();
        users.put(1,"张三");
        users.put(3,"王五");
        users.put(2,null);
        //users.put(null,"翠花");不允许使用null键
        for (Entry e:users.entrySet()
             ) {
            System.out.print(e+ ", ");//1=张三, 2=null, 3=王五, 
        }

        //Hashtable键值对实现,线程安全,Hashtable不允许使用null键和null值。

    }
    }


全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务