Java 集合①

集合产生的原因:

数组可以保存多个对象,但在无法确定需要保存多少个对象时,数组将不再适用,因为数组的长度不可变。
例如,要保存一个学校的学生信息,由于不停有新生来报道,同时也有学员毕业离开学校,这时学生的数目无法固定,并且随时可能变动。
为了保存这些数目不确定的对象,Java中提供了集合,集合可以存储任意类型的对象,并且长度可变。

定义:Java中的集合就像一个容器,专门用来存储Java对象。
说明集合对象可以是任意的数据类型,并且长度可变。
注意:这些集合类都位于java.util包中,在使用时一定要注意导包的问题。
集合分为两大类:
在这里插入图片描述

单列集合(Collection):

1.单列集合用于存储一系列符合某种规则的元素。
2.Collection集合有两个重要的子接口,分别是List和Set。
3.List集合的特点是元素有序、可重复。该接口的主要实现类有ArrayList和LinkedList。
4.Set集合的特点是元素无序丶不可重复。该接口的主要实现类有HashSet和TreeSet。

Collection:

Collection 是接口 不能new
和Map接口区分,添加元素是add方法.
在这里插入图片描述

Collection col1=new ArrayList();
col1.add("a");
col1.add("b");
col1.add("c");
Collection col2=new ArrayList();
col2.add(1);//为什么可以添加基本数据类型?:自动包装
col1.addAll(col2);

List:

定义: List接口继承自Collection 接口是单列集合的一个重要分支,习惯性的会将实现了List接口的对象称为List集合
特点: List集合中有序 且允许出现重复元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引(类似于数组中的元素角标)来访问集合中的元素。
List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致
在这里插入图片描述

ArrayList

说明:
ArrayList是List接口的一个 实现类,它是程序中最常见的一种集合。
ArrayList内部的数据存储结构是数组形式。
特点:
由于ArrayList的存储结构,在增加或删除指定位置的元素时,会创建新的数组,效率比较低,因此不适合做大量的增删操作。
这种数组结构允许程序通过索引的方式来访问元素,使用ArrayList集合在遍历和查找元素时显得非常高效。
实例:

import java.util.ArrayList;
import java.util.List;

public class ArrayLisrDemo1 
{
public static void main(String[] args)
{
	List list=new ArrayList();
	list.add("java");
	list.add("hello");
	list.add("world");
	list.add("good");
	System.out.println(list);
	System.out.println(list.get(3));
	list.set(1, "nimei");
	System.out.println(list);
	System.out.println("集合的长度:" + list.size()); 
	System.out.println("第2个元素是:" + list.get(1));
	System.out.println(list.remove(2));
	System.out.println(list.indexOf("nimei"));
}
}
/*
输出结果:
[java, hello, world, good]
good
[java, nimei, world, good]
集合的长度:4
第2个元素是:nimei
world
1

*/

LinkedList集合(不做重点,掌握特点):

说明:
LinkedList是List接口的 另一个实现类
LinkedList内部包含有两个Node类型的first和last属性的双向循环链表结构。
特点:
由于LinkedList的存储结构, LinkedList集合对于元素的遍历和查找效率较低。
LinkedList集合对于元素的增删操作表现出很高的效率
LinkedList特有的方法:
在这里插入图片描述
在这里插入图片描述

实例:

LinkedList link = new LinkedList();  
link.add("stu1");
link.add("stu2");
link.offer("offer");                    // 向集合尾部追加元素
link.push("push");                  // 向集合头部添加元素
Object object = link.peek();   //获取集合第一个元素
link.removeFirst();                 // 删除集合第一个元素
link.pollLast();                        // 删除集合最后一个元素

Collection集合遍历:

Iterator遍历集合:
定义: Iterator接口是Java集合框架中的一员,主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。

import java.util.List;

public static void main(String []args)
{
	List l=new ArrayList();
	l.add("java");
	l.add("hello");
	l.add("world");
	l.add("good");
	Iterator it=l.iterator();//返回类型就是一个Iterator的对象
	System.out.println(it.next()+" n");
	while(it.hasNext())//hasNext判断是否还有元素.
	{
		String s=(String) it.next();//Object对象转换为String类型
		System.out.println(s);
		
	}
}

/*
输出结果为:
java n
hello
world
good
*/

List迭代器ListIterator
Iterator有一个子类,不仅可以对集合进行从前向后遍历,还可以从后面向前遍

//List迭代器,可以从前向后遍历
		ListIterator lit=list.listIterator();
		while(lit.hasNext()) {//向后遍历
			String str=(String)lit.next();//next返回的Object对象
			System.out.print(str+" ");
		}
		System.out.println();
		while(lit.hasPrevious()) {//向前遍历
			String str=(String)lit.previous();
			System.out.print(str+" ");
		}

foreach遍历集合:

定义: foreach循环是一种更加简洁的for循环,也称 增强for循环,用于遍历数组或集合中的元素。

import java.util.*;

public class JavaArrayListDemo 
{
public static void main(String[]args)
{
	ArrayList<String> list=new ArrayList<String>();
	Collections.addAll(list, "a","t","at");
	Collections.reverse(list);
	printarray(list);
	System.out.println(Collections.max(list));
	Collections.sort(list);
	printarray(list);//这里的printarray方法是自定义的一个方法,不是java的
	Collections.shuffle(list);
	printarray(list);
}
public static void printarray(ArrayList<String> list)
{
	for(String s:list)
		System.out.print(s+" ");
	System.out.println(" ");
}
 }

shuffle方(仅做了解) static void shuffle(List<?> list)
使用默认随机源对列表进行置换,所有置换发生的可能性都是大致相等的。 static void shuffle(List<?> list,
Random rand) 使用指定的随机源对指定列表进行置换,所有置换发生的可能性都是大致相等的,假定随机源是公平的
通俗一点的说,就像洗牌一样,随机打乱原来的顺序。

在这里,集合加了泛型:
泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

  • 一些常用的泛型类型变量:
    E:元素(Element),多用于java集合框架
    K:关键字(Key)
    N:数字(Number)
    T:类型(Type)
    V:值(Value)
    实例:

假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?
答案是可以使用 Java 泛型
使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。

public class MethodTest
{
   // 泛型方法 printArray                         
   public static < E > void printArray( E[] inputArray )
   {
      // 输出数组元素            
         for ( E element : inputArray ){        
            System.out.printf( "%s ", element );
         }
         System.out.println();
    }
 
    public static void main( String args[] )
    {
        // 创建不同类型数组: Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
 
        System.out.println( "整型数组元素为:" );
        printArray( intArray  ); // 传递一个整型数组
 
        System.out.println( "\n双精度型数组元素为:" );
        printArray( doubleArray ); // 传递一个双精度型数组
 
        System.out.println( "\n字符型数组元素为:" );
        printArray( charArray ); // 传递一个字符型数组
    } 
}

JDK 8——forEach遍历集合

定义: forEach(Consumer action)方法是JDK 8中新增的遍历集合元素的方法,根据Lambda表达式特性,该方法所需要的参数是一个函数式接口。

 list.forEach(obj -> System.out.println("迭代集合元素:"+obj));

说明: JDK 8中还针对Iterator迭代器对象提供了一个forEachRemaining(Consumer action)方法来进行遍历,该方法同样需要一个函数式接口。

 Iterator it = list.iterator();
    it.forEachRemaining(obj -> System.out.println("迭代集合元素:"+obj));

遍历所需注意的问题:

  • 1.foreach循环遍历集合和数组时,只能访问集合中的元素,不能对其中的元素进行修改。
  • 2.Iterator迭代器对集合中的元素进行迭代时,如果调用了集合对象的remove()方法删除元素,会出现ConcurrentModificationException异常。

Set

说明: Set接口和List接口一样,同样继承自Collection接口。
特点: Set接口中的元素无序,并且都会以某种规则保证存入的元素不出现重复。
HashSet: 根据对象的哈希值来确定元素在集合中的存储的位置,因此具有良好的存取和查找性能.
TreeSet: 以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序.

HashSet:

说明: HashSet是Set接口的一个实现类,它所存储的元素不可重复,并且无序。
特点: 当向HashSet集合中添加一个元素时,首先会调用该元素的hashCode()方法来确定元素的存储位置,然后再调用元素对象的equals()方法来确保该位置没有重复元素。

注意: 在Java中,一些基本数据包装类、String类等都已经 默认重写了hashCode()和equals()方法。
开发者向HashSet集合中添加自定义的数据类型,如Student类时,必须增加重写的hashCode()和equals()方法,才能保证数据的唯一性。

HashSet set = new HashSet();  
    set.add("Jack");                 
    set.add("Eve");
    ...
    set.forEach(o -> System.out.println(o));//o为参数

TreeSet集合:

说明: TreeSet是Set接口的另一个实现类,它内部采用平衡二叉树来存储元素,来保证TreeSet集合中没有重复的元素,并且可以对元素进行排序。
TreeSet集合还有一些特有的方法。(有兴趣了解)

重点:自然排序和定制排序。

1.自然排序
说明: 要求存储的元素类必须实现Comparable接口,并重写compareTo()方法。

  • 元素类本身实现Comparable接口。
  • 依赖compareTo()方法的实现
  • 实现Comparable接口排序规则比较单一,不利于后续改进。
    步骤:
  • 1.让元素自身具备比较性
  • 2.实现Compareable接口,覆盖其CompareTo方法

import java.util.Set;
import java.util.TreeSet;
//自然排序,有序按照大小
public class TreeSetDemo1 {
	public static void main (String args[])
	{
TreeSet<Teacher> s=new TreeSet<Teacher>();
Teacher t1=new Teacher("zhangsan",20,"aa");
Teacher t2=new Teacher("lisi",30,"bb");
Teacher t3=new Teacher("wangwu",40,"cc");
Teacher t4=new Teacher("luqi",50,"dd");
s.add(t1);
s.add(t2);
s.add(t3);
s.add(t4);
System.out.println(s);
}
}
class Teacher implements Comparable
{
	private String name;
	private int age;
	private String id;
	Teacher(String name,int age,String id)
	{
		super();
		this.name=name;
		this.age=age;
		this.id=id;
	}
	public int compareTo(Object obj)//重写compareTo方法
	{
		if(!(obj instanceof Teacher))
		{throw new RuntimeException("不是老师对象");}//抛出错误
		Teacher t=(Teacher)obj;//将obj强制转换成Teacher类对象
		if(this.age>t.age)
			return 1;
		if(this.age==t.age)
			return 0;
		return -1;
	}
		public String toString()
	{
		return name+" "+age+" "+id;
	}

/*

输出结果:
[zhangsan 20 aa, lisi 30 bb, wangwu 40 cc, luqi 50 dd]
*/
	
}

2.定制排序
说明 : 要求自定义一个比较器,该比较器必须实现Comparator接口,并重写compare()方法,然后将该比较器作为参数传入集合的有参构造。

  • 适合元素类本身未实现Comparable接口,无法进行比较。
  • 适合元素类实现的Comparable接口排序规则无法满足用户需求。
  • 会额外定义一个实现Comparator接口的比较器。
    步骤:
  • 实现comparator接口
  • 复写compare方法
  • 在创建TreeSet集合对象时,提供一个一个Comparator对象,
import java.util.Comparator;
import java.util.TreeSet;
//TreeSet的自定义比较器
public class TreeSetDemo2 
{
public static void main(String[] args)
{
	TreeSet ts=new TreeSet(new Comparator()
			{
		public int compare(Object o1,Object o2)
		{
			String s1=(String)o1;
			String s2=(String)o2;
					return s1.length()-s2.length();//上面自然排序中的简单写法
			
		}
			});//匿名内部类的方式
	ts.add("aa");
	ts.add("456");
	ts.add("ccdr");
	ts.add("dfggg");
	System.out.println(ts);
}
}
/*public class TreeSetDemo2 
{
public static void main(String[] args)
{//兰姆达表达式
	TreeSet ts=new TreeSet((Object o1,Object o2)->
	{
			String s1=(String)o1;
			String s2=(String)o2;
		return s1.length()-s2.length();	
	});
	ts.add("aa");
	ts.add("456");
	ts.add("ccdr");
	ts.add("dfggg");
	System.out.println(ts);
}
}*/
/*class Mycompare implements Comparator
{//单独定义一个类,重写compare方法以长度来比较
public int compare(Object o1,Object o2)
{
	String s1=(String)o1;
	String s2=(String)o2;
			return s1.length()-s2.length();
	
}
}*/
/*
输出结果:
[aa, 456, ccdr, dfggg]
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值