数组就是存储数据的容器,保证多个数据的数据类型要一致,长度固定
public class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat(){
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
public static void main(String[] args) {
//数组定义方式1
int[] arr1 = new int[3];
arr1[0] = 10;
arr1[1] = 11;
arr1[2] = 12;
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
//数组定义方式2
int[] arr2 = new int[]{20, 21, 22};
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
//数组定义方式3
int[] arr3 = {30, 31, 32};
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
//存放自定义类的元素
Cat[] c = new Cat[3];
c[0] = new Cat("xiaohua");
c[1] = new Cat("xiaohei");
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
}
执行结果:
10
11
12
20
21
22
30
31
32
Cat{name='xiaohua'}
Cat{name='xiaohei'}
null
java.util.Arrays
此类包含用来操作数组的各种方法,比如排序和搜索等。其所有方法均为静态方法,调用起来非常简单。
public static String toString(Object[] array)
:返回数组元素的字符串形式。public static void sort(Object[] array)
:对数组按升序进行排序。public static List asList(T... a)
:返回由指定数组支持的固定大小列表。import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
int[] arr = {2,34,35,4,657};
// 数组内容转为字符串
String s = Arrays.toString(arr);
// 打印字符串,输出内容
System.out.println(s); // [2, 34, 35, 4, 657]
//排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // [2, 4, 34, 35, 657]
}
}
作用是返回由指定数组支持的固定大小列表。
注意:这个方法返回的 ArrayList 不是我们常用的集合类 java.util.ArrayList。这里的 ArrayList 是 Arrays 的一个内部类 java.util.Arrays.ArrayList。这个内部类有如下属性和方法:
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
import java.util.Arrays;
import java.util.List;
public class Hello {
public static void main(String[] args) {
String[] s= {"a","b","c"};
List<String> list1 = Arrays.asList(s);
System.out.println(list1.toString()); // [a, b, c]
list1.set(1, "d");
System.out.println(list1.toString()); //[a, d, c]
list1.add("g"); //添加元素报错,java.lang.UnsupportedOperationException
}
}
import java.util.Arrays;
import java.util.List;
public class Hello {
public static void main(String[] args) {
String[] str = {"a","b","c"};
List<String> listStr = Arrays.asList(str);
System.out.println(listStr.size());//3
int[] i = {1,2,3};
List<int[]> listI = Arrays.asList(i);//注意这里List参数为 int[] ,而不是 int
System.out.println(listI.size());//1
Integer[] in = {1,2,3};
List<Integer> listIn = Arrays.asList(in);//这里参数为int的包装类Integer,所以集合长度为3
System.out.println(listIn.size());//3
}
}
上面的结果第一个listStr.size()==3,而第二个 listI.size()==1。这是为什么呢?
我们看源码,在 Arrays.asList 中,方法声明为 List asList(T… a)。该方法接收一个可变参数,并且这个可变参数类型是作为泛型的参数。我们知道基本数据类型是不能作为泛型的参数的,但是数组是引用类型,所以数组是可以泛型化的,于是 int[] 作为了整个参数类型,而不是 int 作为参数类型。
String[] str = {"a","b","c"};
List<String> listStr = Arrays.asList(str);
//执行更新操作前
System.out.println(Arrays.toString(str));//[a, b, c]
listStr.set(0, "d");//将第一个元素a改为d
//执行更新操作后
System.out.println(Arrays.toString(str));//[d, b, c]
我们看修改集合的内容,原数组的内容也变化了,所以这里传入的是引用类型。
String[] str = {"a","b","c"};
List<String> listStr = new ArrayList<>(Arrays.asList(str));
listStr.add("d");
System.out.println(listStr.size());//4
System.out.println(listStr.toString());
Arrays工具类提供了一个方法asList, 使用该方法可以将一个变长参数或者数组转换成List 。但是,生成的List的长度是固定的;能够进行修改操作(比如,修改某个位置的元素);不能执行影响长度的操作(如add、remove等操作),否则会抛出UnsupportedOperationException异常。
所以 Arrays.asList 比较适合那些已经有数组数据或者一些元素,而需要快速构建一个List,只用于读取操作,而不进行添加或删除操作的场景。
集合是java中提供的一种容器,可以用来存储多个数据。
集合和数组既然都是容器,它们有什么区别呢?
Collection是单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是
java.util.List
和 java.util.Set
。其中, List 的特点是元素有序、元素可重复。 Set 的特点是元素不可重
复。 List 接口的主要实现类有 java.util.ArrayList
和 java.util.LinkedList
, Set 接口的主要实现类有
java.util.HashSet
和 java.util.LinkedHashSet
。
注意:这张图只是我们常用的集合有这些,不是说就只有这些集合。
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。下面给出Collection中一些常用的方法
public boolean add(E e)
: 把给定的对象添加到当前集合中 。public void clear()
:清空集合中所有的元素。public boolean remove(E e)
: 把给定的对象在当前集合中删除。public boolean contains(Object obj)
: 判断当前集合中是否包含给定的对象。public boolean isEmpty()
: 判断当前集合是否为空。public int size()
: 返回集合中元素的个数。public Object[] toArray()
: 把集合中的元素,存储到数组中java.util.List 接口继承自 Collection 接口,是单列集合的一个重要分支,习惯性地会将实现了 List 接口的对象称为List集合。
List接口特点:
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操
作集合的特有方法:
public void add(int index, E element)
: 将指定的元素,添加到该集合中的指定位置上。public E get(int index)
:返回集合中指定位置的元素。public E remove(int index)
: 移除列表中指定位置的元素, 返回的是被移除的元素。public E set(int index, E element)
:用指定元素替换集合中指定位置的元素,返回值的更新前的元素java.util.ArrayList
集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为
查询数据、遍历数据,所以 ArrayList 是最常用的集合。
许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。
java.util.LinkedList 集合数据存储的结构是链表结构。方便元素添加、删除的集合。
java.util.Set
接口和 java.util.List
接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方
法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不
同的是, Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
java.util.HashSet
是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序
不能保证不一致)。 java.util.HashSet
底层的实现其实是一个 java.util.HashMap
支持,
HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存储和查找性能。保证元素唯一性
的方式依赖于: hashCode 与 equals 方法。
在HashSet下面有一个子类 java.util.LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构。可以保证元素唯一且元素存放有序。
java.utils.Collections
是集合工具类,用来对集合进行操作。
常用方法如下:
public static void shuffle(List> list)
:打乱集合顺序。public static void sort(List list)
:将集合中元素按照默认规则排序。public static void sort(List list,Comparator super T> )
:将集合中元素按照指定规则排序。ArrayList<Integer> list = new ArrayList<>();
list.add(100);
list.add(300);
list.add(200);
list.add(50);
System.out.println(list); //[100, 300, 200, 50]
//排序方法
Collections.sort(list);
System.out.println(list); //[50, 100, 200, 300]
Collection 中的集合称为单列集合, Map 中的集合称为双列集合。
Collection 中的集合,元素是孤立存在的,向集合中存储元素采用一个个元素的方式存储。Map 中的集合,元素是成对存在的。每个元素由键与值两部分组成,通过键可以找对所对应的值。Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
Map接口中定义了很多方法,常用的如下:
public V put(K key, V value)
: 把指定的键与指定的值添加到Map集合中。public V remove(Object key)
: 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。public V get(Object key)
根据指定的键,在Map集合中获取对应的值。public Set keySet()
: 获取Map集合中所有的键,存储到Set集合中。public Set> entrySet()
: 获取到Map集合中所有的键值对对象的集合(Set集合)。public boolean containKey(Object key)
:判断该集合中是否有此键。通过查看Map接口描述,看到Map有多个子类,这里我们主要讲解常用的HashMap集合、LinkedHashMap集合。
存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。【键保证不重复,但是元素存储无序】
HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。【键保证不重复,且元素存储有序】
注意:Map接口中的集合都有两个泛型变量,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量的数据类型可以相同,也可以不同。
HashMap<String, String> map = new HashMap<>();
map.put("dog", "狗");
map.put("cat", "猫");
map.put("bird", "鸟");
map.put("pig", "猪");
System.out.println(map); //{cat=猫, bird=鸟, dog=狗, pig=猪}
map.remove("cat");
System.out.println(map); //{bird=鸟, dog=狗, pig=猪}
//遍历map方式1:键找值方式
Set<String> keySet = map.keySet();
for (String key: keySet){
System.out.println(map.get(key));
}
/*输出
鸟
狗
猪
*/
//遍历map方式2:键值对方式
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> entry: entrySet){
System.out.println(entry.getKey()+": "+entry.getValue());
}
/*输出
bird: 鸟
dog: 狗
pig: 猪
*/
方式1:键找值方式
通过元素中的键,获取键所对应的值
方式2:键值对方式
键值对方式即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
Entry键值对对象:
Entry将key-value的一 一对应关系封装为对象即键值对对象。我们可以从每一个键值对( Entry )对象中获取对应的键与对应的值。
在Map集合中也提供了获取所有Entry对象的方法:
public Set> entrySet()
: 获取到Map集合中所有的键值对对象的集合(Set集合)。获取了Entry对象 , 表示获取了一对键和值,那么同样Entry中 , 分别提供了获取键和获取值的方法:
public K getKey()
:获取Entry对象中的键。public V getValue()
:获取Entry对象中的值。
参考:
Java中List和ArrayList的区别(理解设计思想)
JDK1.8源码(四)——java.util.Arrays 类