Java基础语法之集合Collection

编程入门 行业动态 更新时间:2024-10-24 20:17:56

Java基础<a href=https://www.elefans.com/category/jswz/34/1770552.html style=语法之集合Collection"/>

Java基础语法之集合Collection

目录

集合简介

 Collection集合

list集合

 Iterator的并发修改异常

增强版的for循环遍历数组或者遍历Collection集合

ArrayList集合

引用数据类型概论

2.引用数据类型分类

引用数据类型和基本数据类型的区别

LinkList集合中特有的方法

set集合

hashSet集合

LinkedHashSet集合

判断集合元素是否唯一的原理

TreeSet集合

泛型


集合简介

 java集合中提供了为Collection接口和Map接口

Colloction接口和Map接口的不同

Conlloction接口实现的子类时实现而Map的子类则是以键值对的形式存储的

接下来我们来看看集合体系

 Collection集合

是接口 不能实力化对象,所以可以用它的子类实例化(向上转型)利用多态的形式

Collection集合的常用方法(前面是返回值类型)

Collection集合常用方法
方法名说明
boolean add(E e)添加元素
boolean remove(Object o)从集合中移除指定元素

void clear()

清空集合中的所有元素
boolean contains(Object o)判断集合中是否包含此元素
boolean isEmpty()判断集合是否为空
int size()获得集合的长度

C

 Collection 集合的遍历

Iterator 迭代器 集合类通用的遍历方式 用迭代器迭代遍历

Iterator 接口也是java集合框架的成员,它的对象被称为迭代器

定义了如下几个方法

boolean hasNext();    如果集合还没有遍历完则返回true

Object  next()     从集合中获取下一个元素

void remove();       删除集合里上一次next方法返回的元素

注意Iterator 必须依赖于集合对象是从集合中获取

案例代码

package day6;import java.util.*;public class Collection{public static void main(String[] args) {
//创建一个对象``````java.util.Collection<Student> c=new ArrayList<>();//创建学生对象Student s1=new Student("凌青霞",30);Student s2=new Student("李四",320);Student s3=new Student("王五",230);//添加元素c.add(s1);c.add(s2);c.add(s3);c.remove(s2);boolean isNull=   c.isEmpty();boolean  contains=c.contains(s1);int size=c.size();System.out.println("集合是否为空"+isNull);System.out.println("集合中是否包含s1"+contains);System.out.println("集合长度"+size);System.out.println("=======================");//遍历集合Iterator<Student> it=c.iterator();while (it.hasNext()){Student ss=it.next();System.out.println("name   " +ss.getName());System.out.println("age   "+ss.getAge());}}
}

运行结果

集合是否为空false
集合中是否包含s1true
集合长度2
=======================
name   凌青霞
age   30
name   王五
age   230

list集合

List集合是Collection集合的子接口  可以得到父接口的所有方法

接口不能实例化对象所以要依靠多态

List接口的常用子类有:

  1. ArrayList集合
  2. LinkedList集合

list集合的特点

  1. 可以重复
  2. 存储有序,可以序号遍历(索引是从0开始)

继承Collection集合

具有父类接口方法

 List特有的方法

  void add( int index,Object element); 将指定元素添加到指定位置

Object  get(int index);   获得指定索引的元素

int indexOf(Object o);  获得指定元素第一次出现的索引

int lastIndex(Object o)   获得指定元素最后一次出现的索引

Object remove(int index);    删除指定索引的元素并返回

Object set(int index,Object o); 修改指定索引的元素并返回

案例使用

package day6;import java.util.ArrayList;
import java.util.Iterator;public class List {public static void main(String[] args) {//创建集合对象java.util.List<String> list=new ArrayList<String>();//添加元素list.add("hello");list.add("world");list.add("java");list.add("java");/*Void add(int index,E e);  //插入指定元素
E remove(int index)  //删除索引出指定元素
E set(int index,E e)//修改指定索引处的元素,返回修改后的元素
E  get(int index)//获得索引的元素*/list.add(1,"插入到1位置的元素");list.remove(2);list.set(3,"修改后的java");String s =list.get(2);System.out.println("获得指定索引元素"+s);//可以重复//输出集合对象System.out.println(list);//迭代器遍历Iterator<String> it=  list.iterator();while (it.hasNext()){String its=it.next();System.out.println(its);}}
}

运行结果

 Iterator的并发修改异常

要求条件 在list集合中,对元素进行判断,一旦满足条件就新添加一个新的元素

public class IteratorDemo {
//在list集合迭代元素中,对元素进行判断,一旦条件满足就添加一个新元素public static void main(String[] args) {//创建List集合List<String> list = new ArrayList<String>();//给集合中添加元素list.add("abc1");list.add("abc2");list.add("abc3");list.add("abc4");//迭代集合,当有元素为"abc2"时,集合加入新元素"itcast"Iterator<String> it = list.iterator();while(it.hasNext()){String str = it.next();//判断取出的元素是否是"abc2",是就添加一个新元素if("abc2".equals(str)){list.add("itcast");// 该操作会导致程序出错}}//打印容器中的元素System.out.println(list);}
}

运行上述代码发生了错误 java.util.ConcurrentModificationException[L1] 这是什么原因呢?

在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性。

经过查看Iterator源码可知


并发修改异常

/modCount:实际修改的次数  当调用add()方法时 ++;但是expectedModCount没有改变
//expectedModCount预期修改的次数
//        it.next();
//        方法有一个判断 if(expectedModCount==modCount:)

如果两者不相等的就会抛出异常

1、for循环根据索引遍历修改

for (int i=0;i<list.size();i++){String s=list.get(i);if (s.equals("world")){list.add("javaEE") ;}}System.out.println(list);
}

2、

用ListIterator可以解决 ,其中含有add()方法

会把实际的修改值,赋值给预期的修改值;

ListIterator<String> list2=new list.listIterator();
while (list2.hasNext()){String s=it.next();if (s.equals("world")){list.add("javaEE");}
}

增强版的for循环遍历数组或者遍历Collection集合

增强版的for循环实现原理

实现类Iterable接口的类 

  1. 其对象成为增强版的for语句的目标
  2. 其实他是JDK5之后出现的,其内部原理是一个Iterator迭代器
     

增强版的for循环格式

for(元素类型变量: 数组或Collection集合)

{

此处变量即可,该变量就是元素

}

for (int i=0;i<list.size();i++){System.out.println(list.get(i));
}for (String s:list){System.out.println(s+"世界正大");}//测试增强版的for循环是iterator实现类for (String s2:list){if (s2.equals("world")){list.add("javaEe");//报并发修改异常}}

结果

 案例

package day6.StudentListBianli;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class students {public static void main(String[] args) {
//创建学生对象Student s=new Student("张三",15);Student s2=new Student("王五",15);Student s3=new Student("李四",15);
//        String ss1=s.getName();
//        String ss2=s2.getName();
//        String ss3=s3.getName();//创建集合对象List<Student> list=new ArrayList<Student>();list.add(s);list.add(s2);list.add(s3);//普通遍历for(int i=0;i<list.size();i++){System.out.println(list.get(i).getAge());}//增强for循环for(Student n:list){System.out.println(n.getName());}//Iterator遍历Iterator <Student> it=list.iterator();while (it.hasNext()){System.out.println(it.next().getAge());}}
}

ArrayList  和linkList 集合的特点

ArrayList 底层的数据结构是数组,查询快,增删慢

LinkList  底层是链表增删快,查询慢

ArrayList集合

特有的方法

  1. Object remve(int index) 从集合中删除指定index处的元素,返回该元素

ArrayList集合是程序中最常见的一种集合,它属于引用数据类型(类)。在ArrayList内部封装了一个长度可变的数组,当存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素,因此可以将ArrayList集合看作一个长度可变的数组。

声明格式

ArrayList<数据类型> 变量名 =new  ArrayList<数据类型>;

<>数据类型的要求

  1. 集合中存储的元素,只能为<>括号中指定的数据类型元素;
  2. “<要存储元素的数据类型>”中的数据类型必须是引用数据类型,不能是基本数据类型;

那什么事引用数据类型呢

引用数据类型概论

  • 引用数据类型 变量名 这样声明的时候变量为null。
  • 引用数据类型 变量名=new 引用数据类型,例如String a=new String("hi~")这时候内存存储如图:

  •  

    这时候String a 在栈内存中声明了 一个内存地址,内存地址指向堆内存中new String("hi~")声明的对象。即变量名为引用的内存地址。

2.引用数据类型分类


  • Object object= new Integer(1); //来定义一个Interger类
  • 接口
    接口不能直接new进行实例化,可以引用实现接口的类。
  • 数组
    int[] a=new int[10];

引用数据类型和基本数据类型的区别

一、从概念方面来说

基本数据类型:变量名指向具体的数值

引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值

二、从内存构建方面来说

基本数据类型:变量在声明之后java就会立刻分配给他内存空间

引用数据类型:它以特殊的方式(类似C指针)指向对象实体(具体的值),这类变量声明时不会分配内存,只是存储了一个内存地址。

接下来我给出8中基本数据类型对应的引用数据类型

基本数据类型

对应的引用数据类型表示形式

byte

Byte

short

Short

Int

Integer

long

Long

float

Float

double

Double

char

Character

boolean

Boolean

LinkList集合中特有的方法

LinkList 底层是链表增删快,查询慢

public void addFirst(E e)   向列表中开头插入指定元素

public void addLast(E e)   向列表插入指定元素

public E getFist();   返回列表中第一个元素

public E getLast();   返回列表中末尾的一个元素

Public E removeFist();  删除并返回第一个元素

Public E removeLast(e);  删除并返回最后一个元素

set集合

是Collection接口的子接口

set集合的特点

1、不能存储重复元素 ,元素的唯一

2、没有带索引的方法所以不能存取索引的方法遍历

package day7;import java.util.HashSet;public class Set {public static void main(String[] args) {//HashSet:对集合的迭代顺序不做保障//不包含重复元素java.util.Set <String> set=new HashSet<String>();//添加元素set.add("hello");set.add("he033");set.add("hjava");set.add("hjava");set.add("022");set.add("hjava");for(String s:set){System.out.println(s);}}
}

hashSet集合

首先我们来解释

一个概念  哈希表

 如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

HashSet 唯一性

HashSet集合 底层采取的是哈希表结构存储结构  依赖于hashCode()与equals()方法

同一个对象中多次调用hasCode();哈希值相同

默认情况下不同对象的哈希值是不同的但是可以相同,就是重写hasCode()方法

HashSet 存储元素

存储JavaAPI中的元素不需要重新hashCode();和equals()方法,api中已经重写完毕

存储自定义数据类型时要重写hashCode()和equals() 方法建立自己的比较方式才能保证集合对象的唯一性

public class Student {private String name;private int age;public Student(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;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if(!(obj instanceof Student)){System.out.println("类型错误");return false;}Student other = (Student) obj;return this.age ==  other.age && this.name.equals(other.name);}
}	创建HashSet集合,存储Student对象。
public class HashSetDemo {public static void main(String[] args) {//创建HashSet对象HashSet hs = new HashSet();//给集合中添加自定义对象hs.add(new Student("zhangsan",21));hs.add(new Student("lisi",22));hs.add(new Student("wangwu",23));hs.add(new Student("zhangsan",21));//取出集合中的每个元素Iterator it = hs.iterator();while(it.hasNext()){Student s = (Student)it.next();System.out.println(s);}}
}

结果

输出结果如下,说明集合中不能存储重复元素:

Student [name=lisi, age=22]

Student [name=zhangsan, age=21]

Student [name=wangwu, age=23]

LinkedHashSet集合

特点  既保证了元素的唯一性有保证了元素是有序的

底层是它是链表和哈希表组合的一个数据存储结构。

public class LinkedHashSetDemo {public static void main(String[] args) {Set<String> set = new LinkedHashSet<String>();set.add("bbb");set.add("aaa");set.add("abc");set.add("bbc");
Iterator it = set.iterator();while (it.hasNext()) {System.out.println(it.next());}}
}

结果

输出结果如下,LinkedHashSet集合保证元素的存入和取出的顺序:

bbb

aaa

abc

bbc

判断集合元素是否唯一的原理

ArrayList 的contains方法判断是否有重复元素

boolean  contains(Object o);

返回列表中是否包含此元素

那么自定义类型中并没有重写eauals方法前,判断是否重复是地址值,那么如果要比较元素的内容是否相等就必须重写equals方法

HashSet的add/contains 方法判断

 set集合不添加重复元素

HashSet 集合是无序的,

其判断唯一的依据是元素类型的hashCode与equals方法的返回结果。规则如下:

先判断新元素与集合内已经有的旧元素的HashCode值

  1. 如果不同,说明是不同元素,添加到集合。

如果相同,再判断equals比较结果。返回true则相同元素;返回false则不同元素,添加到集合。

自定义类型需要重写hashcode和equals方法

TreeSet集合

特点

1、元素有序 ,是按照一定的规则进行排序的,具体的排序方式取决于构造方法

2.TreeSet();根据器元素的字眼潘旭进行排序(默认)

3.TreeSet(Comparator comparator)指定比较器比较

案例

package day7;import java.util.HashSet;
import java.util.TreeSet;public class Set {public static void main(String[] args) {
//创建集合TreeSet<Integer> ts=new TreeSet<Integer>();//添加元素ts.add(10);ts.add(40);ts.add(30);ts.add(30);for (Integer s:ts){//自然排序从小到大System.out.println(s);//结果// 1// 0//30//40}}public  class  Generid<T>{private  T t;public T getT() {return t;}public void setT(T t) {this.t = t;}public void show(T t){System.out.println(t);}}}

结果

   //结果
            // 1
            // 0
            //30
            //40

案例2 指定规则排序

package day7;import java.util.Comparator;
import java.util.TreeSet;public class TreeSet02 {public static void main(String[] args) {//Comparable自然排序 该接口对实现它的每一个对象强加一个整体排序,这个排序称之为自然排序  并且可以去除重复元素TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {int num=s1.getAge()-s2.getAge();int num2=num==0?s1.getName()pareTo(s2.getName()):num;return num2;}});//创建对象Student s=new Student("aaa",19) ;Student s2=new Student("zzzz",12) ;Student s3=new Student("cc",18) ;Student s4=new Student("ddd",56) ;Student s5=new Student("ee",20) ;ts.add(s);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);//遍历for (Student ss:ts){System.out.println("姓名"+ss.getName()+"年龄"+ss.getAge());}}
}

结果

姓名zzzz年龄12
姓名cc年龄18
姓名aaa年龄19
姓名ee年龄20
姓名ddd年龄56

Process finished with exit code 0

泛型

定义

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,

操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

具体使用

泛型的参数需要哪一种类型直接调用即可相当于一个参数

定义格式

修饰符 class 类名 <类型> {}

Public class Generic<T> {}

Gnerid<String> str =new Gnerid<String>();

Str.show(“字符串类型”);

Gnerid<Interger> i=new Gnerid  <Interger>();

  1. show(100);

泛型接口实现泛型接口

public calss Gerneriidzilei <T> implements Gerneriid <T> {

   System.out.println(t);

}



 

更多推荐

Java基础语法之集合Collection

本文发布于:2024-03-05 03:51:36,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1711240.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:语法   基础   Java   Collection

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!