Java中的集合(collection)
Java中的集合Collection是底层抽取的一个接口,下面有许多的实现类或者是抽象类来实现该接口。
Java中的迭代器(iterator)用户遍历各种不同集合中的元素。
Collection<String> coll=new ArraryList<>();
/*
集合中常用的共性方法:
1.add往集合中添加元素,返回值添加成功为true,否则为false;
2.remove往集合中删除某个元素,如果有删除成功就返回true,否则false;
3.contains,判断集合中是否包含某元素,返回值boolean类型
4.clear,清空集合中的元素
5.toArrary,将集合变成数组,方便遍历
6.size,判断集合中的元素个数,返回值为int类型的集合个数
7.isEmpty,判断集合是否为空,为空true,否则false
*/
public static void main(String[] args) {
Collection<String> collection=new ArrayList<>();
System.out.println(collection);
boolean result = collection.add("张三");
collection.add("张三1");
collection.add("张三2");
collection.add("张三3");
collection.add("张三4");
boolean b = collection.remove("张三5");
boolean d = collection.contains("张三");
boolean empty = collection.isEmpty();
int size = collection.size();
Object[] objects = collection.toArray();
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
collection.clear();
System.out.println(collection);
System.out.println(size);
System.out.println(empty);
System.out.println(d);
System.out.println(b);
System.out.println(result);
System.out.println(collection);
}
迭代器
的原理:先判断集合是否为空,如果不为空就取出来这个元素,取出来之后,再继续判断集合是否为空,如果还未空,继续取出元素,直到集合为空为止。
迭代器iterator是一个接口,所以我们并不能直接new一个对象,就需要使用到Java中的多态。每一个集合中都有一个iterator接口的实现类,所以可以采用多态创建对象的方式创建出来迭代器对象。
注意
:迭代器也是和集合一样有泛型的,通过集合对象的iterator方法创建的对象的泛型与集合的泛型保持一致,关于泛型的好处,我们之后介绍。
iterator迭代器中常用的方法有两种:hasnext()返回值是boolean类型的,通过判断集合是否为空来取下一个元素,还有一个方法是next()直接取出下一个元素。
public static void main(String[] args) {
Collection<String> collection=new ArrayList<>();
collection.add("小明");
collection.add("小明1");
collection.add("小明2");
collection.add("小明3");
collection.add("小明4");
Iterator<String> iterator = collection.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
增强型for循环也是内部使用了迭代器
的原理,使用for循环的方式简化了迭代器的书写。(在jdk1.5之后出现的新特性)
Collection extends Iteratable,所有的单列集合都可以使用foreach增强型for循环。
增强型for循环的使用方式:
for(集合或数组的数据类型 变量名:集合或数组名){
System.out.println(变量名);
}
//数组和集合增强型for循环
public static void main(String[] args) {
Collection<String> coll=new ArrayList<>();
coll.add("小王");
coll.add("小华");
coll.add("小明");
coll.add("小李");
for (String i:coll ) {
System.out.println(i);
}
int[] a=new int[]{1,2,3,4,5,6,7};
for (int s :a ) {
System.out.println(s);
}
}
Collection接口下面有两大接口,分别是list接口和set接口
list接口的三大特点:
1.有序的集合,存入数据的顺序和取出数据的顺序一致;
2.存入的数据元素可以相同;
3.list接口含有索引,可以通过索引取值,存值,遍历等操作,但需要注意不要索引值越界。
list接口的实现类有许多,其中常用的有个arraylist<>类,Linkedlist<>类
其中arraylist类的本质也是数组,对数组的重新复制创建,所以查找快,增删慢。
Linkedlist集合底层是链表结构,所以查询慢,增删快,里面包含了大量操作首尾的方法,不能使用多态创建对象。
Set接口的特点:
1.不包含重复的值,即不可以存储相同的元素。
2.没有索引,所以不能使用索引的方法进行for循环遍历。
Set接口的实现类有HashSet类。
可变参数:
可变参数是jdk1.5之后出现的,它是当方法的参数列表类型确定了,但是参数的个数不确定时使用。
使用格式:
修饰符 返回值类型 方法名(变量类型 …变量名){}
可变长参数底层是创建了一个变量类型[变量个数]的数组。
public static void main(String[] args) {
System.out.println(sum(1));
System.out.println(sum(1,2,3,4,5,6,7,8,9,10));
}
public static int sum(int ...args){//创建了args数组,数组的长度就是传入参数的个数,可以是0-n
int sum=0;
for (int arg : args) {
sum+=arg;
}
return sum;
}
注意
可变长参数的书写规范:
1.一个方法的可变长参数…只能有一个;
2.如果有多个参数在一个方法中,可变长参数只能写在该方法所有参数的最后,比如下面这个。
public static void add(String username,int age,int ...args){
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("my name is "+username+"and my age is "+age+"and my attribute is");
for (int arg : args) {
stringBuilder.append(arg);
}
System.out.println(stringBuilder);
}
public static void Test(Object ...objects){
}
Collections中的常用静态方法:
shuffle();//随机打乱list的元素顺序;sort方法,将list中的数据按照顺序进行排序,对于String,Integer类型的数据按照ASCALL码字母顺序表进行升序排序,对于自定义数据类型,需要将自定义引用数据类型实现Compare接口,重写Compareto方法,例如:
public class Student implements Comparable<Student> {
private String username;
private int age;
public Student() {
}
public Student(String username, int age) {
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
@Override
public String toString() {
return "Student{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Student o) {
return this.age-o.age;//升序
}
}
Map接口:
Map(K,V)
Map集合的特点:
1.map集合是一个双列集合,而collection集合是单列集合;
2.map集合中的键值对一一对应,键值不允许重复,但是值可以重复;
3.map集合中的键的数据类型与值得数据类型可以相同也可以不同。
map的常用实现类,HashMap<>,LinkedHashMap<>.
HashMap<>类拥有Map接口的特点,键值不允许重复,所以这是String键值,String类内部封装的时候重写了Hashcode和equals方法,所以能够判断相同的键就会把后面相同键对应的值代替前面键相同的值。
public static void method1(){
Map<String,Person> map=new HashMap<>();
map.put("小明",new Person("小明",18));
map.put("小华",new Person("小华",20));
map.put("小花",new Person("小花",17));
map.put("明明",new Person("明明",20));
map.put("小明",new Person("小明",18));
System.out.println(map);
Set<Map.Entry<String, Person>> entries = map.entrySet();
Iterator<Map.Entry<String, Person>> iterator = entries.iterator();
while (iterator.hasNext()){
Map.Entry<String, Person> next = iterator.next();
System.out.println(next.getKey()+"====>"+next.getValue());
}
}
HashMap<>类如果键是自定义引用类型,如Person类,就需要在Person类封装的时候重写HashCode和equals方法,保证键不重复,如果不重写HashCode和equals方法,对象的属性值相同也会认为是不同的键值,如:
//Person类内部:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//方法
public static void method2(){
Map<Person,String> map=new HashMap<>();
map.put(new Person("小明",18),"小明");
map.put(new Person("小花",16),"小花");
map.put(new Person("小华",20),"小华");
map.put(new Person("小明",18),"小明");
map.put(new Person("笨蛋",22),"小明");
System.out.println(map);
}
LinkedHashMap<>类是一个有序的集合,它底层采用的是数组+链表的方式,链表的加入保证了存取数据的有序,但也是双列集合,且键值对一一对应,键不允许重复。
private static void method3() {
Map<String,String> map=new LinkedHashMap<>();
map.put("小明","17");
map.put("小明","18");
map.put("小华","17");
map.put("小花","15");
System.out.println(map);
}