集合
由来:对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定,就是用集合容器进行存储
集合特点:
1 用于存储对象的容器。
2 集合的长度是可变的。
3 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。
不断的向上抽取,就形成了集合框架。
框架的顶层Collection接口:
Collection的常见方法:
boolean | add(E e) 确保此 collection 包含指定的元素(可选操作)。 | |
boolean | addAll(Collection<? extendsE> c) 将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 | |
void | clear() 移除此 collection 中的所有元素(可选操作)。 | |
boolean | contains(Object o) 如果此 collection 包含指定的元素,则返回 true。 | |
boolean | containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 true。 | |
boolean | equals(Object o) 比较此 collection 与指定对象是否相等。 | |
int | hashCode() 返回此 collection 的哈希码值。 | |
boolean | isEmpty() 如果此 collection 不包含元素,则返回 true。 | |
Iterator<E> | iterator() 返回在此 collection 的元素上进行迭代的迭代器。 | |
boolean | remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 | |
boolean | removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 | |
boolean | retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 | |
int | size() 返回此 collection 中的元素数。 | |
Object[] | toArray() 返回包含此 collection 中所有元素的数组。 | |
| toArray(T[] a) 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 |
迭代器Iterator
boolean | hasNext() 如果仍有元素可以迭代,则返回 true。 |
E | next() 返回迭代的下一个元素。 |
void | remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。 |
Iterator
对象必须依赖于具体容器,因为每一个容器的数据结构都不同。所以该迭代器对象是在
容器中进行内部实现的。对于使用容器者而言,具体地实现不重要,只要通过容器获取到该实现
的迭代器的对象即可,也就是iterator方法。
Interator 接口就是对所有的Collection容器进行元素取出的公共接口。
例:
public static void show1(Collection c1){
c1.add("abc1");
c1.add("abc2");
c1.add("abc5");
//使用Object 中的iterator方法获取Iterator 的一个对象
Iterator it = c1.iterator();
c1.add("abc1");
c1.add("abc2");
c1.add("abc5");
//使用Object 中的iterator方法获取Iterator 的一个对象
Iterator it = c1.iterator();
遍历全部元素一:
while(it.hasNext()){
System.out.println(it.next());
}
while(it.hasNext()){
System.out.println(it.next());
}
遍历全部元素二:
for(Iterator it = c1.iterator();it.hasNext();){
System.out.println(it.next());
}
for(Iterator it = c1.iterator();it.hasNext();){
System.out.println(it.next());
}
List : 有序(存入和取出的顺序一致),元素 都有索引(角标),元素可以重复。
Set:元素不能重复。无序 ,方法与Collection一致
List:特有的常见方法: 有一个共性特点就是可以操作角标。
1 添加
void add(index,element)
void add(index,collection)
2 删除
Object remove(index)//返回被删掉的元素
3 修改
Object set(index,element)
4 获取
Object get(index)
int indexOf(object)
int lastIndexOf(object)
List subList(from,to)
//包含头不包含尾
List 可以完成对元素的增删改查
例:
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
ListIterator it = list.listIterator();//获取列表迭代器对象 ListIterator为 Iterator的子接口
while(it.hasNext()){ //它可以实现在迭代过程中完成对元素的增删改查
//注意只有List集合具备该迭代功能
Object obj = it.next();
if(obj.equals("abc2")){//在
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
ListIterator it = list.listIterator();//获取列表迭代器对象 ListIterator为 Iterator的子接口
while(it.hasNext()){ //它可以实现在迭代过程中完成对元素的增删改查
//注意只有List集合具备该迭代功能
Object obj = it.next();
if(obj.equals("abc2")){//在
}迭代器过程中,不要使用集合操作元素,容易出现异常
it.add("abc9");// ListIterator 迭代器有add方法
}
System.out.println(list);
it.add("abc9");// ListIterator 迭代器有add方法
}
System.out.println(list);
注意:
/*
Iterator it = list.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("abc2")){//在迭代器过程中,不要使用集合操作元素,容易出现异常
list.add("abc9");//java.util.ConcurrentModificationException
}
else
System.out.println("next:"+obj);
}
System.out.println(list);
*/
/*
Iterator it = list.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("abc2")){//在迭代器过程中,不要使用集合操作元素,容易出现异常
list.add("abc9");//java.util.ConcurrentModificationException
}
else
System.out.println("next:"+obj);
}
System.out.println(list);
*/
}
}
List:常用子类
1 Vector:内部是数组数据结构,是同步的。
2 ArrayList:内部是数组数据结构,是不同步的。替代了Vector 查询速度快
3 LinkedList:内部是链表数据结构,是不同步的。 增删元素快
以上长度都是可变的。
LinkedList 练习:
请用LinkedList来模拟一个堆栈或者队列数据结构。
堆栈:先进后出结构
队列:先进先出结构
应该描述这样一个容器,提供一个对象完成这两种数据结构
class DuiLie{
private LinkedList list;
DuiLie(){
list = new LinkedList();
}
public void myadd(Object obj){
list.addLast(obj);
}
public Object myGet(){
return list.removeFirst();
}
public boolean isNull(){
return list.isEmpty();
}
}
堆栈:先进后出结构
队列:先进先出结构
应该描述这样一个容器,提供一个对象完成这两种数据结构
class DuiLie{
private LinkedList list;
DuiLie(){
list = new LinkedList();
}
public void myadd(Object obj){
list.addLast(obj);
}
public Object myGet(){
return list.removeFirst();
}
public boolean isNull(){
return list.isEmpty();
}
}
public class LinkedTest {
public static void main(String[] args) {
DuiLie d = new DuiLie();
d.myadd("abc1");
d.myadd("abc2");
d.myadd("abc3");
while(!d.isNull()){
System.out.println(d.myGet());
}
}
}
ArrayList练习:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class ArrayTest {
public static void main(String[] args) {
ArrayList arr = new ArrayList();
arr.add(new Person("lisi1",21));
arr.add(new Person("lisi2",22));
arr.add(new Person("lisi3",23));
arr.add(new Person("lisi4",24));
Iterator it = arr.iterator();
while(it.hasNext()){
//System.out.println(( (Person) it.next()).getName()+"::"+((Person) it.next()).getAge());
//这里如果直接加getName() 会报错,因为it.next() 返回的是
//Object对象,而Object没有getName方法 所以得强制转换
//如果这里为两个next()就会输出lisi1::22
//lisi3::24 因为next()是一次一次执行的 不会一次执行两个next()
Person p = (Person) it.next();
System.out.println(p.getName()+"--"+p.getAge());
}
}
}
ArrayList练习:
去除ArrayList 中的相同元素
思路:
1 用另一个ArrayList 存储其中的元素
2 判断已存入元素是否含有将要存入的元素,如果没有,则存入
public class ArrayListDemo {
public static void main(String[] args) {
1 用另一个ArrayList 存储其中的元素
2 判断已存入元素是否含有将要存入的元素,如果没有,则存入
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList a = new ArrayList();
a.add(new Person("lisi1",22));
a.add(new Person("lisi1",22));
a.add(new Person("lisi1",23));
a.add(new Person("lisi1",23));
System.out.println(a);
a = getSingleElement(a);
System.out.println(a);
}
public static ArrayList getSingleElement(ArrayList a){
ArrayList tmp = new ArrayList();
Iterator it = a.iterator();
while(it.hasNext()){
Object obj = it.next();
if(!tmp.contains(obj))//如果判断的为自定义的对象,其实 contains方法调用的是equals 方法。
tmp.add(obj);
}
return tmp;
}
}
set的常用子类:
1 HashSet: 内部数据结构是哈希表,是不同步的。
HashSet的子类LinkedHashSet可以使元素变得有序。
哈希值:根据对象本身利用算法得出一个值,从而确定它的位置。
哈希表确定元素是否相同:
1 判断的是两个元素的哈希值是否相同。
如果相同,在判断两个对象的内容是否相同
2 判断哈希值相同,其实判断的是对象的hashCode的方法。判断内容相同,用的是equals方法。
注意:如果哈希值不同,是不需要判断equals。
练习:
往HashSet 存储Person对象,如果姓名年龄相同,则视为同一个元素。
public class HashTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
/* 每个对象的地址不同,equals比较就是不同的,所以HashSett会认为有五个对象。
* 所以需要 在Person 中重写HashCode 方法和equals
Person 重写equals方法
/*
public boolean equals(Object obj) {
if(this==obj)
return true;
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode() {
return name.hashCode()+age;
}
public boolean equals(Object obj) {
if(this==obj)
return true;
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode() {
return name.hashCode()+age;
}
*/
hs.add(new Person("lisi4",24));
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi1",21));
hs.add(new Person("lisi9",29));
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person) it.next();
System.out.println(p.getName()+"...."+p.getAge());
}
}
}
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi1",21));
hs.add(new Person("lisi9",29));
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person) it.next();
System.out.println(p.getName()+"...."+p.getAge());
}
}
}
2 TreeSet::可以对set集合中的元素进行排序,是不同步的。
判断元素唯一性的方式:根据比较方法的返回结果是否为0,为0就是相同元素
Tree对元素进行排序的方式之一:
让元素自身具备比较功能,
元素就需要实现Comparable接口。覆盖compareTo方法。(大于返回一个正整数,小于返回负整数,小于返回0)
如果不按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序中,怎么办?
可以使用TreeSet集合第二种排序方式二:
让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。
方式一:
public class TreeSetDemo {
public static void main(String[] args) {
/*TreeSet会进行排序,而此时Person类没有继承Comparable,所以无法比较。
在Person类实现Comparator接口实现方法:
public int compareTo(Object obj) {
第二种方式(简写):Person p = (Person)obj;
int tmp = this.age-p.age;
return tmp==0?this.name.compareTo(p.name):tmp;//String类已经实现了Comparable
第一种方式:Person p = (Person)obj;
if(this.age>p.age)
return 1;
if(this.age<p.age)
return -1;
else{
return this.name.compareTo(p.name); // 年龄相等的情况下,比较姓名。
}
*/
TreeSet set = new TreeSet();
set.add(new Person("wangwu",29));
set.add(new Person("lisi",22));
set.add(new Person("sayu",21));
set.add(new Person("lisi",23));
Iterator it = set.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
public int compareTo(Object obj) {
第二种方式(简写):Person p = (Person)obj;
int tmp = this.age-p.age;
return tmp==0?this.name.compareTo(p.name):tmp;//String类已经实现了Comparable
第一种方式:Person p = (Person)obj;
if(this.age>p.age)
return 1;
if(this.age<p.age)
return -1;
else{
return this.name.compareTo(p.name); // 年龄相等的情况下,比较姓名。
}
*/
TreeSet set = new TreeSet();
set.add(new Person("wangwu",29));
set.add(new Person("lisi",22));
set.add(new Person("sayu",21));
set.add(new Person("lisi",23));
Iterator it = set.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
方式二:
public class TreeSetDemo {
public static void main(String[] args) {
/*
public class CompareByName implements Comparator {
public int compare(Object a, Object b) {
Person p1 = (Person)a;
Person p2 = (Person)b;
int tmp = p1.getName().compareTo(p2.getName());
return tmp==0?p1.getAge()-p2.getAge():tmp; //如果想要按照输入顺序进行排序,直接返回1
}
}*/
TreeSet set = new TreeSet (new CompareByName());
set.add(new Person("wangwu",29));
set.add(new Person("lisi",22));
set.add(new Person("sayu",21));
set.add(new Person("lisi",23));
Iterator it = set.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
小Tips:
需要唯一吗?
需要:Set:
需要制定顺序吗?
需要:TreeSet
不需要:HashSet(需要一个和存储一致的顺序时:LinkedHashSet)
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
List
1 ArrayList
2 LinkedList
Set
1 HashSet
2 TreeSet
后缀名就是该集合所属的体系。
前缀名就是该集合的数据结构。
看到array:就要想到数组,就要想到查询快,有角标
看到Link:就要想到链表,就要想到增删快,就要想到add,get,remove+first,last的方法
看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashCode方法和equals方法
看到tree:就要想到二叉树,想到排序,想到两个接口Comparable,Comparator
通常这些容器是不同步的。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Map:一次添加一对元素。Collection 一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实Map集合中存储的就是键值对。
map集合中必须保证键的唯一性。
常用方法:
1 添加:
value put(key,value):返回前一个和key关联的值,如果没有返回null (键值相同,值会覆盖)
2 删除
void clear();清空map集合
value remove(key):根据指定的key得出这个值。
3 判断
boolean containKey(key):
boolean conyainValue(value):
boolean isEmpty();
4 获取
value get(key):通过键获取值,如果没有该键返回null
当然可以通过返回null,来判断是否包含指定键。
int size();获取键值对的个数。
其他方法:
Collection<V> | values() 返回此映射中包含的值的 Collection 视图。 |
取出元素:
public class MapDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method(map);
}
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method(map);
}
public static void method(Map<Integer,String> map){
/*取出map的所有元素:
原理:通过keySet()方法获取键的Set集合,再通过Set的迭代器获取每一个键
最后通过map的get()方法获取每一个键对应的值*/
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+":"+value);
}
}
}
第二种方法 entrySet
*/
/*通过Map转成Set就可以迭代
* 第二种方法 entrySet
* 该方法将键和值得映射关系作为对象存储到了Set集合中,而这个映射关系类型就是Map.Entry类型
* */
/*通过Map转成Set就可以迭代
* 第二种方法 entrySet
* 该方法将键和值得映射关系作为对象存储到了Set集合中,而这个映射关系类型就是Map.Entry类型
* */
(接上面)例:
Set<Map.Entry<Integer,String>> entrySet = map.entrySet();//Entry为Map的静态内部接口
Iterator<Map.Entry<Integer,String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Integer,String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::"+value);
Set<Map.Entry<Integer,String>> entrySet = map.entrySet();//Entry为Map的静态内部接口
Iterator<Map.Entry<Integer,String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Integer,String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::"+value);
}
Map常用的子类:
1 Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值
2 HashMap: 内部结构是哈希表,不是同步的。允许null作为键,null作为值
子类:LingkedHashMap:取出的顺序和存储一的顺序一致。
3 TreeMap;每部结构是二叉树,不是同步的。可以对Map集合中的键进行排序
4 Properties:用来存储键值对型的配置文件的信息,可以和io技术相结合。
练习:
"vavavbafafs" 记录字符串中字符出现的次数
* 按格式输出:例:a(1) b(2) c(2)
* 按格式输出:例:a(1) b(2) c(2)
/*"vavavbafafs" 记录字符串中字符出现的次数
* 按格式输出:例:a(1) b(2) c(2)
* 思路:因为字符与次数存在映射关系,所以可以用Map集合存储这些映射关系。
* 因为字符输出格式是有序的,所以可以用TreeMap存储。
* 1 将字符串转换为字符数组。
* 2 遍历字符数组,判断Map集合中是否含有该字符,有的话,取出对应的字符(键)的值
* 使值加1;再把字符作为键存入Map集合(键相同,值会覆盖),没有的话字符作为键,1作为值进行存储。
* 3 遍历结束
* */
public class MapTest {
public static void main(String[] args) {
String str = "vav a ++ vba A fa DDfs";
String s = getCharCount(str);
System.out.println(s);
}
public static String getCharCount(String str) {
// 将字符串变为字符数组 toCharArray()
char[] chs = str.toCharArray();
// 建立一个Map集合
Map<Character, Integer> map = new TreeMap<Character, Integer>();// TreeMap对键进行排序
// 进行判断
for (int i = 0; i < chs.length; i++) {
if (!((chs[i] >= 'a' && chs[i] <= 'z') || (chs[i] >= 'A' && chs[i] <= 'Z')))
continue;
Integer s = map.get(chs[i]);
if (s == null) {
map.put(chs[i], 1);
} else {
s++;
map.put(chs[i], s);
}
}
return maptoString(map);
}
private static String maptoString(Map<Character, Integer> map) {
StringBuilder sb = new StringBuilder();
Iterator<Character> it = map.keySet().iterator();
while (it.hasNext()) {
Character key = it.next();
Integer value = map.get(key);
sb.append(key + "(" + value + ")");
}
return sb.toString();
}
}
* 按格式输出:例:a(1) b(2) c(2)
* 思路:因为字符与次数存在映射关系,所以可以用Map集合存储这些映射关系。
* 因为字符输出格式是有序的,所以可以用TreeMap存储。
* 1 将字符串转换为字符数组。
* 2 遍历字符数组,判断Map集合中是否含有该字符,有的话,取出对应的字符(键)的值
* 使值加1;再把字符作为键存入Map集合(键相同,值会覆盖),没有的话字符作为键,1作为值进行存储。
* 3 遍历结束
* */
public class MapTest {
public static void main(String[] args) {
String str = "vav a ++ vba A fa DDfs";
String s = getCharCount(str);
System.out.println(s);
}
public static String getCharCount(String str) {
// 将字符串变为字符数组 toCharArray()
char[] chs = str.toCharArray();
// 建立一个Map集合
Map<Character, Integer> map = new TreeMap<Character, Integer>();// TreeMap对键进行排序
// 进行判断
for (int i = 0; i < chs.length; i++) {
if (!((chs[i] >= 'a' && chs[i] <= 'z') || (chs[i] >= 'A' && chs[i] <= 'Z')))
continue;
Integer s = map.get(chs[i]);
if (s == null) {
map.put(chs[i], 1);
} else {
s++;
map.put(chs[i], s);
}
}
return maptoString(map);
}
private static String maptoString(Map<Character, Integer> map) {
StringBuilder sb = new StringBuilder();
Iterator<Character> it = map.keySet().iterator();
while (it.hasNext()) {
Character key = it.next();
Integer value = map.get(key);
sb.append(key + "(" + value + ")");
}
return sb.toString();
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
集合框架工具类
Collections
static
| binarySearch(List<? extendsComparable<? super T>> list, T key) 使用二分搜索法搜索指定列表,以获得指定对象。 | |
static
| binarySearch(List<? extends T> list, T key,Comparator<? super T> c) 使用二分搜索法搜索指定列表,以获得指定对象。 |
static
| max(Collection<? extends T> coll) 根据元素的自然顺序,返回给定 collection 的最大元素。 | |
static
| max(Collection<? extends T> coll,Comparator<? super T> comp) 根据指定比较器产生的顺序,返回给定 collection 的最大元素。 | |
static
| min(Collection<? extends T> coll) 根据元素的自然顺序 返回给定 collection 的最小元素。 | |
static
| min(Collection<? extends T> coll,Comparator<? super T> comp) 根据指定比较器产生的顺序,返回给定 collection 的最小元素。 |
static void | reverse(List<?> list) 反转指定列表中元素的顺序。 | |
static
| reverseOrder() 返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。 |
static
| sort(List<T> list) 根据元素的自然顺序 对指定列表按升序进行排序。 | |
static
| sort(List<T> list,Comparator<? super T> c) 根据指定比较器产生的顺序对指定列表进行排序。 | |
static void | swap(List<?> list, int i, int j) 在指定列表的指定位置处交换元素。 | |
static
| synchronizedCollection(Collection<T> c) 返回指定 collection 支持的同步(线程安全的)collection。 | |
static
| synchronizedList(List<T> list) 返回指定列表支持的同步(线程安全的)列表。 | |
static
| synchronizedMap(Map<K,V> m) 返回由指定映射支持的同步(线程安全的)映射。 | |
static
| synchronizedSet(Set<T> s) 返回指定 set 支持的同步(线程安全的)set。 | |
static
| synchronizedSortedMap(SortedMap<K,V> m) 返回指定有序映射支持的同步(线程安全的)有序映射。 | |
static
| synchronizedSortedSet(SortedSet<T> s) 返回指定有序 set 支持的同步(线程安全的)有序 set。 |
Arrays的方法都是静态的
重点:Arrays工具的List asList(数组)将数组转成集合。
好处:其实可以使用集合的方法操作数组中的元素。
注意:数组的长度是固定的,所以对集合的增删方法是不可以使用的
否则会发生UnsupportedOperationException
如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
如果数组中的元素是基本数据类型数值,那么会将该
数组作为集合中的元素进行存储。
jdk1.5新特性
Collection 继承了Iterable ,它只有一个iterator方法
foreach语句
格式for(类型 变量:集合|数组){} 简化迭代的书写
函数可变参数 int... (注意:可变参数需要写在方法的列表里,变长的参数必须放在形参的最后,一个方法不能接受两组变长参数)
可变长参数可以理解为用数组存储数据
例:实现多个数的相加
public void add(int...nums){
int sum = 0;
for(int i =0;i<nums.length;i++){ sum+=nums[i] ; }
}
静态导入
import static java.util.Collection.*; 其实导入的是类中的静态成员