史上最全讲解:Java中的二维数组与容器

史上最全讲解: Java中的二维数组与容器

二维数组

定义

数组中存放着数组

语法格式

  • 声明 数据类型[][] 数组名

  • 初始化

    动态初始化: 数据类型[][] 数组名 = new 数据类型[一维的长度][二维的长度];

    ​ 数据类型[][] 数组名 = new 数据类型[一维的长度][];

    ​ 静态初始化:数据类型[][] 数组名 = new 数据类型[][]{{‘a’,‘b’},{‘c’,‘d’,‘e’},{‘f’}};

    ​ 数据类型[][] 数组名 = {{‘a’,‘b’},{‘c’,‘d’,‘e’},{‘f’}};

  • 遍历 增强for循环 普通for循环

Arrays

  • 操作数组的工具类,静态工厂
  • 使用方式:Arrays.静态方法名
  • copyOf, fill, equals,sort,toString

容器

定义

容器

  • 容器: 存储多个数据,可以是不同数据类型,长度不定
  • 变量:存储单个数据,数据类型确定
  • 数组:存储多个数据,数据类型唯一,且定长

注意: 容器中的元素类型都为引用类型不能放置原生数据类型(使用装箱即可),使用泛 型保留类型

自定义容器类

package com.shsxt.collection02;
import java.util.Arrays;
/ * 自定义容器类:
 * 	MyContainer 只能存储字符串数据 ,内部使用数组存储,查询效率高,增删效率低 
 */
public class App01 {
	public static void main(String[] args) {
		//一个容器已经存在
		MyContainer my=new MyContainer();
		//存储数据
		my.add("钢铁侠");
		my.add("蜘蛛侠");
		my.add("奇异博士");
		System.out.println(my.size());
		System.out.println(my);
		//获取
		System.out.println(my.get(0));
		System.out.println(my.get(1));
		System.out.println(my.get(2));
		//修改数据(index,数据)
		System.out.println(Arrays.toString(my.revise(2,"123")));
		//删除数据(index)
		System.out.println(Arrays.toString(my.delete(0)));
	}
}

//自定义容器类
class MyContainer{
	private String[] arr;  //真实内部存储数据的结构
	private int size; //容器中存储数据的个数 有默认值0
	
	public MyContainer() {
		arr=new String[0];
	}

	public String[] delete(int index) {
		// TODO Auto-generated method stub
		String[] temp = arr;
		arr = new String[size-1];
		int j = 0;
		for(int i=0;i<size;i++){
			arr[j] = temp[i];
			if(j==index){
				i++;
				arr[index] = temp[i];
			}
			j++;
		}
		return arr;
	}

	public String[] revise(int index,String value) {
		// TODO Auto-generated method stub
		String[] temp = arr;
		arr = new String[size];
		int j = 0;
		for(int i=0;i<size;i++){
			arr[j] = temp[i];
			if(j==index){
				arr[index] = value;
				continue;
			}
			j++;
		}
		return arr;
	}

	//根据索引获取内容 
	public String get(int index) {
		if(index<0 || index>=size){
			throw new ArrayIndexOutOfBoundsException();
		}
		return arr[index];
	}

	/*
	 * 添加功能 
	 */
	public void add(String value) {
		//对原数组进行备份
		String[] temp=arr;  //原数组
		arr=new String[size+1]; //新数组
		//数组的拷贝,原数组中的数据需要拷贝到新数组中
		//原数组拿到每一个数据,赋值
		for(int i=0;i<=size-1;i++){
			arr[i]=temp[i];
		}
		arr[size]=value;
		size++;
	}
	
	public int size(){
		return this.size;
	}

	@Override
	public String toString() {
		return "MyContainer [arr=" + Arrays.toString(arr) + ", size=" + size + "]";
	}
}

Collection

Collection是容器的顶层接口

Collection 表示一组对象,它是集中,收集的意思,就是把一些数据收集起来,

Collection 接口的两个子接口:Set 中的数据没有顺序,不可重复;List 中的数据有顺序,可重复

泛型 提高可读性,规范数据的类型

格式:

Collection<String> col = new ArrayList<String>();
  • 常见方法

    booleanadd(E e) 确保此 collection 包含指定的元素(可选操作)。
    booleancontains(Object o) 如果此collection包含指定元素则返回true
    Iteratoriterator 返回在此 collection 的元素上进行迭代的迭代器。
    booleanequals(Object o) 比较此 collection 与指定对象是否相等。

iterator遍历

使用是迭代器的步骤:

使用迭代器时,分三步走策略:

第一步:获取对象 ;第二步:判断是否存在下一个;第三步:获取元素

package com.shsxt.list03;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class ListDemo01 {
	public static void main(String[] args) {
		Collection<String> col = new ArrayList<String>();
		col.add("这个杀手不太冷");
		col.add("泰坦尼克号");
		col.add("tom and Jerry");
		Iterator it = col.iterator();
		while(it.hasNext()){
			System.out.println(it.next());;
		}
	}
}

List

  • List接口特点: 有序(索引),可重复
  • 新增方法:可以根据索引操作的方法
  • 遍历:增强for,普通for,迭代器 iterator
    ListIterator
package com.shsxt.list03;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
 * 定义一个容器,存放你喜欢的外国电影名,如果存在 这个杀手不太冷,就添加一个哈哈哈(必须要存在这个杀手不太冷...)
 *  	判断的方式有很多中,都去使用一下看看
 */
public class ListDemo02 {
	public static void main(String[] args) {
		List<String> ls=new ArrayList();
		ls.add("钢铁侠");
		ls.add("飓风营救");
		ls.add("碟中谍");
		ls.add("这个杀手不太冷");
		ls.add("当幸福来敲门");
		System.out.println(ls);
		System.out.println(ls.contains("这个杀手不太冷"));
		ListIterator<String> it=ls.listIterator();
		//测试使用 boolean hasPrevious() previous() 从后往前逆向遍历list容器
		while(it.hasNext()){
			it.next();
		}
		while(it.hasPrevious()){
			if("这个杀手不太冷".equals(it.previous())){
				it.add("哈哈哈");
			}	
		}
		System.out.println(ls);
	}
}

ArrayList
  •  数据结构: 可变数组实现的
    
  •  特点:根据索引进行查询,遍历效率高,增删效率低,涉及到数据的拷贝问题
    
  •  扩容机制:使用copyOf方法进行动态扩容,为原容量的1.5倍
    
  •  新增方法:无新增方法
    
package com.shsxt.list03;
/*去创建list的实现类对象,简单操作练习
 * 定义ArrayList,存储Person类型的数据,
 * 判断new Person("张三",18)在容器中第一次出现的索引
 */
import java.util.ArrayList;
import java.util.List;

public class ArrayListDemo03 {
	public static void main(String[] args) {
		List<Person> ls = new ArrayList<Person>();
		ls.add(new Person("张三",18));
		ls.add(new Person("李四",18));
		ls.add(new Person("王五",18));
		System.out.println(ls);
		Person person = new Person("张三",18);
		System.out.println(person);
		System.out.println(ls.indexOf(person));;
	}

	
}
 class Person {
	 private String name;
	 private int 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 Person() {
		
	}
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	} 
 }
Vector

与ArrayList非常像,区别: 1)线程安全的,效率较低 2)每次扩容是原容量的2倍

LinkedList
  •  数据结构: 双向链表实现
    
  •  特点:做增删效率高,遍历|根据索引查询效率低
    
  •  新增方法:新增了一些操作与链表头尾的方法
    

Set

  • 特点:无序(存放的顺序和内容真实存储的顺序不一致),不可重复的,可以实现去重效果

  • 遍历:

    for …each

    iterator

HashSet
  • 底层结构: 哈希表实现(数组+链表+红黑树)

  • 特点: 查询效率高,增删效率高,但是无序

  • 底层是由HashMap维护的,就是HashMap中的key

  • 使用最多的HashSet方法:

    HashSet() 默认初始16个大小,加载因子0.75

    HashSet( int initialCapacity) 指定容量的容器,当能够确定存储数据的个数,就是用这个构造器

    public class SetDemo02 {
    	public static void main(String[] args) {
    		HashSet hash=new HashSet();
    		hash.add("哈哈");
    		hash.add("哈哈");
    		hash.add("哈哈");
    		hash.add("哈哈");
    		hash.add("哈哈");
    		System.out.println(hash);
    	}
    }
    

t() 默认初始16个大小,加载因子0.75

HashSet( int initialCapacity) 指定容量的容器,当能够确定存储数据的个数,就是用这个构造器

public class SetDemo02 {
	public static void main(String[] args) {
		HashSet hash=new HashSet();
		hash.add("哈哈");
		hash.add("哈哈");
		hash.add("哈哈");
		hash.add("哈哈");
		hash.add("哈哈");
		System.out.println(hash);
	}
}

处理HashSet存储的 自定义应用数据类型的去重问题,需要重写hashcode和equals方法,这两个的值都会根据成员属性来计算而不是地址值,hash表结构的特点是先调用hashcode如果值相同在调用equals方法
set类型会进行比较,而list不会因为list可以重复.对于基本数据类型和String类型set会比较,但是其他引用数据类型需要自己定义比较规则.Hashset实现comparable接口

package com.shsxt.set01;

import java.util.HashSet;
/*
 * 处理HashSet存储的自定义引用数据类型去重问题:
 * 	需要对这个对象类型中重写hashcode和equals方法,然后这个两个的值都根据对象的成员属性值进行计算,而非地址值
 * 	hash表结构的特点是先调用hashcode,如果值形同的对象才会进一步调用equals方法进行比较内容,如果hashcode值不相同,根本不会比较equals方法的值
 * 
 */
public class HashSet01 {
	public static void main(String[] args) {
		HashSet<Person> set=new HashSet();
		set.add(new Person("胡歌",35));
		set.add(new Person("杨洋",30));
		set.add(new Person("彭于晏",35));
		set.add(new Person("彭于晏",35));
		System.out.println(set);
	}
}

package com.shsxt.set01;
//Person类
public class Person implements Comparable<Person> {  //泛型T - 可以与此对象进行比较的那些对象的类型
//public class Person {  
	private String name;
	private int age;
	 
	public Person() {
		// TODO Auto-generated constructor stub
	}

	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;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	//重写equals方法,比较对象时比较对象的内容,非地址
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}

TreeSet
  • TreeSet: 无序,不可重复
  • 底层结构: 红黑树进行存储
  • 特点: 有序(自动从小到达升序排序) 这里的顺序不是元素插入的顺序 而是对于元素进行比较后的排序
  • 可以定义比较规则,**排序规则(compare比较大小进行排序),**并且可以使用去重原则
  • 1 内部比较器|自然排序: **实现Comparable接口,重写comparaTo方法,**在方法中定义比较规则.,默认的比较规则
  • 2外部比较器|指定比较器:**实现一个Comparator接口,重写compare()方法,**方法的内部定义比较规则
    内部比较器的例子
    Person实现comparable接口重写compareTo方法
package com.shsxt.set01;
import java.util.HashSet;
public class HashSet01 {
	public static void main(String[] args) {
		HashSet<Person> set=new HashSet();
		set.add(new Person("胡歌",35));
		set.add(new Person("杨洋",30));
		set.add(new Person("彭于晏",35));
		set.add(new Person("彭于晏",35));
		System.out.println(set);
	}
}
Person类实现了Comparable接口进行比较
package com.shsxt.set01;
public class Person implements Comparable<Person> {  //泛型T - 可以与此对象进行比较的那些对象的类型
//public class Person {  
	private String name;
	private int age;
	public Person() {
		// TODO Auto-generated constructor stub
	}
	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;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	//重写equals方法,比较对象时比较对象的内容,非地址
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	//根据年龄进行比较,年龄相同就是一个对象
	@Override
	public int compareTo(Person o) {
		//return this.age-o.age;
//		return this.age-o.age;
		return this.getName().compareTo(o.getName());//根据正负值自动进行排序
	}
}

外部比较器的例子

package com.shsxt.set01;
//Person类也为上面的Person
import java.util.Comparator;
import java.util.TreeSet;

public class TreeSet02 {
	public static void main(String[] args) {
		//TreeSet tree = new TreeSet(new Demo());
		//Comparator com = (o1, o2)-> ((Person)o1).getAge()-((Person)o1).getAge();
		TreeSet tree = new TreeSet((o1, o2)-> ((Person)o1).getAge()-((Person)o2).getAge());//Lambda表达式
		tree.add(new Person("吴彦祖",18));
		tree.add(new Person("彭于晏",20));
		tree.add(new Person("刘德华",22));
		System.out.println(tree);
	}
}
//下面的类是一个实现类 只是为了单纯实现Comparator接口
//可以上面使用Lambda表达式
class Demo implements Comparator<Person>{
	@Override
	public int compare(Person o1, Person o2) {
		// TODO Auto-generated method stub
		return o2.getAge()-o1.getAge();
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值