黑马程序员java学习日记——集合框架

------- android培训java培训、期待与您交流! ----------

Java.util包中提供了一些集合类,这些集合类又被称为容器。集合类与数组的不同之处是,数组长度是固定的,集合的长度是可变的;数组用来存放基本类型的数据,集合用来存放对象的引用。常用的集合有List集合、Set集合、Map集合,其中ListSet集合继承了Collection接口。各接口还提供了不同的实现类。常用集合类的继承关系图:

Collection

      |--List:元素是有序的,元素可以重复。因为该集合体系有索引。

             |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

             |--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。

             |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。

      |--Set:元素是无序,元素不可以重复。

Collection定义了集合框架的共性功能。

1,添加

      add(e);

      addAll(collection);

2,删除

      remove(e);

      removeAll(collection);

      clear();

3,判断。

      contains(e);

      isEmpty();

4,获取

      iterator();

      size();

5,获取交集。

      retainAll();

6,集合变数组。

      toArray();

注意:1add方法的参数类型是Object。以便于接收任意类型对象。

2,集合中存储的都是对象的引用(地址)

迭代器其实就是集合的取出元素的方式。会直接访问集合中的元素。所以将迭代器通过内部类的形式来进行描述。通过容器的iterator()方法获取该内部类的对象。

import java.util.*;
class  CollectionDemo
{
	public static void main(String[] args) 
	{
		method_get();
method_2();
base_method();
	}
	public static void method_get()
	{
		ArrayList al = new ArrayList();
		//1,添加元素。
		al.add("java01");//add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");
		/*
		Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素。
		while(it.hasNext())//与下面for循环功能相同
		{
			sop(it.next());
		}
		*/
		for(Iterator it = al.iterator(); it.hasNext() ; )
		{
			sop(it.next());
		}
	}
	public static void method_2()
	{
		ArrayList al1 = new ArrayList();
		al1.add("java01");
		al1.add("java02");
		al1.add("java03");
		al1.add("java04");
		ArrayList al2 = new ArrayList();
		al2.add("java03");
		al2.add("java04");
		al2.add("java05");
		al2.add("java06");
		//al1.retainAll(al2);//取交集,al1中只会保留和al2中相同的元素。
		al1.removeAll(al2);

		sop("al1:"+al1);
		sop("al2:"+al2);
	}
	public static void base_method()
	{
		//创建一个集合容器。使用Collection接口的子类。ArrayList
		ArrayList al = new ArrayList();
		//1,添加元素。
		al.add("java01");//add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");
		//打印原集合。
		sop("原集合:"+al);
		//3,删除元素。
		//al.remove("java02");
		//al.clear();//清空集合。
		//4,判断元素。
		sop("java03是否存在:"+al.contains("java03"));
		sop("集合是否为空?"+al.isEmpty());
		//2,获取个数。集合长度。
		sop("size:"+al.size());
		//打印改变后的集合。
		sop(al);
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

List介绍:

List:特有方法。凡是可以操作角标的方法都是该体系特有的方法。

      add(index,element);

      addAll(index,Collection);

      remove(index);

      set(index,element);

      get(index):

      subList(from,to);

      listIterator();

      int indexOf(obj):获取指定元素的位置。

      ListIterator listIterator();

List集合特有的迭代器。ListIteratorIterator的子接口。

在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。此异常当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取。

import java.util.*;
class ListDemo 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void method()
	{
		ArrayList al = new ArrayList();
		//添加元素
		al.add("java01");
		al.add("java02");
		al.add("java03");
		sop("原集合是:"+al);
		//在指定位置添加元素。
		al.add(1,"java09");
		//删除指定位置的元素。
		//al.remove(2);
		//修改元素。
		//al.set(2,"java007");
		//通过角标获取元素。
		sop("get(1):"+al.get(1));
		sop(al);
		//获取所有元素。
		for(int x=0; x<al.size(); x++)
		{
			System.out.println("al("+x+")="+al.get(x));
		}
		Iterator it = al.iterator();//使用迭代器进行遍历
		while(it.hasNext())
		{
			sop("next:"+it.next());
		}
		//通过indexOf获取对象的位置。
		sop("index="+al.indexOf("java02"));
		List sub = al.subList(1,3);
		sop("sub="+sub);
	}
	public static void main(String[] args) 
	{
		//演示列表迭代器。
		ArrayList al = new ArrayList();
		//添加元素
		al.add("java01");
		al.add("java02");
		al.add("java03");
		sop(al);
		ListIterator li = al.listIterator();
		//sop("hasPrevious():"+li.hasPrevious());
		while(li.hasNext())
		{
			Object obj = li.next();
			if(obj.equals("java02"))
				//li.add("java009");
				li.set("java006");
		}
		while(li.hasPrevious())//反向迭代
		{
			sop("pre::"+li.previous());
		}
		//sop("hasNext():"+li.hasNext());
		//sop("hasPrevious():"+li.hasPrevious());
		sop(al);
		/*
		//在迭代过程中,准备添加或者删除元素。
		Iterator it = al.iterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if(obj.equals("java02"))
				//al.add("java008");
				it.remove();//将java02的引用从集合中删除了。
			sop("obj="+obj);
		}
		sop(al);
		*/
	}
}

ArrayList类实现了可变的数组,允许所有元素,包括null,并可以根据索引位置对集合进行快速的随机访问。缺点是向指定的索引位置插入对象或删除对象的速度较慢。

练习题:去除ArrayList集合中的重复元素。

代码如下:

import java.util.*;
class ArrayListTest 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();//建立集合并添加元素
		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java02");
		al.add("java01");
		sop(al);
		al = singleElement(al);//调用singleElement方法
		sop(al);
	}
	public static ArrayList singleElement(ArrayList al)
	{
		//定义一个临时容器。
		ArrayList newAl = new ArrayList();
		Iterator it = al.iterator();//对临时容器迭代
		while(it.hasNext())
		{
			Object obj = it.next();
			if(!newAl.contains(obj))
				newAl.add(obj);
		}
		return newAl;
	}
}

LinkedList类采用链表结构保存对象。这种结构的优点是便于向集合中插入和删除对象,需要向集合中插入、删除对象时,使用LinkedList类实现List集合的效率较好;但对于随机访问集合中的对象,使用LinkedList类实现List集合的效率较慢。

LinkedList:特有方法:

addFirst();

addLast();

 

getFirst();

getLast();

获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

 

removeFirst();

removeLast();

获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException

 

JDK1.6出现了替代方法。

offerFirst();

offerLast();

 

peekFirst();

peekLast();

获取元素,但不删除元素。如果集合中没有元素,会返回null

pollFirst();

pollLast();

获取元素,但是元素被删除。如果集合中没有元素,会返回null

代码:

import java.util.*;
class LinkedListDemo 
{
	public static void main(String[] args) 
	{
		LinkedList link = new LinkedList();
		link.addLast("java01");
		link.addLast("java02");
		link.addLast("java03");
		link.addLast("java04");
		//sop(link);
//sop(link.getFirst());//获取集合中第一个数据
		//sop(link.getLast());//获取集合中最后一个数据
		//sop(link.removeFirst());//将集合中第一个数据删除
		//sop("size="+link.size());//获取集合长度
		while(!link.isEmpty())//判断集合是否为空
		{
			sop(link.removeLast());
		}
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

Set集合:

Set集合中的对象不按特定的方式排序,只是简单地把对象加入集合中,但Set集合终不能包含重复对象。Set集合由Set接口和Set接口的实现类组成。Set接口继承了Collection接口,因此包含Collection接口的所有方法。

HashSet类实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证Set的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用null元素。而且它的线程是不安全的,不同步。它是通过元素的两个方法hashCodeequals来保证元素的唯一性,如果元素的HashCode值相同,才会判断equals是否为true,如果元素的hashcode值不同,不会调用equals

注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcodeequals方法。

Set集合的功能和Collection是一致的。

代码演示:

import java.util.*;
class HashSetDemo 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		HashSet hs = new HashSet();//建立集合对象
		sop(hs.add("java01"));//打印true,因为集合中没有java01
		sop(hs.add("java01"));//打印false,因为集合中有java01
		hs.add("java02");
		hs.add("java03");
		hs.add("java03");
		hs.add("java04");
		Iterator it = hs.iterator();//对集合进行迭代
		while(it.hasNext())
		{
			sop(it.next());
		}
	}
}

TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,因此,TreeSet类实现的Set集合在遍历集合时按照自然顺序递增排序,也可以是按照指定比较器递增排序,即可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。

底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0.

TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。

代码练习:排序第一种方式

需求:

TreeSet集合中存储自定义对象学生。

按照学生的年龄进行排序。排序时,当主要条件相同时,一定判断一下次要条件。

import java.util.*;
class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet();//建立集合对象
		ts.add(new Student("lisi02",22));//添加元素
		ts.add(new Student("lisi007",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi08",19));
		Iterator it = ts.iterator();//对集合进行迭代
		while(it.hasNext())
		{
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());
		}
	}
}
class Student implements Comparable//该接口强制让学生具备比较性。
{
	private String name;
	private int age;
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	public int compareTo(Object obj)
	{
		if(!(obj instanceof Student))//判断传入的数据是不是学生对象
			throw new RuntimeException("不是学生对象");//不是就抛出异常
		Student s = (Student)obj;
		System.out.println(this.name+"....compareto....."+s.name);
		if(this.age>s.age)//对年龄进行比较
			return 1;
		if(this.age==s.age)//如果年龄相等就比较姓名
		{
			return this.name.compareTo(s.name);
		}
		return -1;
		}
}

TreeSet的第二种排序方式。当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。方法是定义一个类,实现Comparator接口,覆盖compare方法。

import java.util.*;
class GenericDemo2 
{
	public static void main(String[] args) 
	{
		TreeSet<String> ts = new TreeSet<String>(new LenComparator());//将新定义的比较方式传入,使集合具备比较性
		ts.add("abcd");//添加元素
		ts.add("cc");
		ts.add("cba");
		ts.add("aaa");
		ts.add("z");
		ts.add("hahaha");
		Iterator<String> it = ts.iterator();//对元素进行迭代
		while(it.hasNext())
		{
			String s = it.next();
			System.out.println(s);
		}
	}
}
class LenComparator implements Comparator<String>//新建类继承Comparator
{
	public int compare(String o1,String o2)
	{
		int num = new Integer(o2.length()).compareTo(new Integer(o1.length()));
		if(num==0)
			return o2.compareTo(o1);
		return num;
	}
}

泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。

好处:

1.将运行时期出现问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时问题减少,安全。

2,避免了强制转换麻烦。

泛型格式:通过<>来定义要操作的引用数据类型。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

泛型通常在集合框架中很常见,只要见到<>就要定义泛型。其实<> 就是用来接收类型的。

代码实现:

import java.util.*;
class GenericDemo 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc01");
		al.add("abc0991");
		al.add("abc014");
		Iterator<String> it = al.iterator();
		while(it.hasNext())
		{
			String s = it.next();
			System.out.println(s+":"+s.length());
		}
	}
}

泛型类:

当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。现在定义泛型来完成扩展。

代码实现:

import java.util.*;
class Worker
{
}
class Student
{
}
class Utils<QQ>//泛型类
{
	private QQ q;
	public void setObject(QQ q)
	{
		this.q = q;
	}
	public QQ getObject()
	{
		return q;
	}
}
class  GenericDemo3
{
	public static void main(String[] args) 
	{
		Utils<Worker> u = new Utils<Worker>();
		u.setObject(new Student());
		Worker w = u.getObject();;
	}
}

泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。

特殊之处:

静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

import java.util.*;
class Demo<T>
{
	public  void show(T t)
	{
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q)//将泛型加载方法上
	{
		System.out.println("print:"+q);
	}
	public  static <W> void method(W t) //将泛型加载方法上
	{
		System.out.println("method:"+t);
	}
}
class GenericDemo4 
{
	public static void main(String[] args) 
	{
		Demo <String> d = new Demo<String>();
		d.show("haha");
		d.print(5);
		d.print("hehe");
		Demo.method("hahahahha");
    }
}

泛型定义在接口上。

import java.util.*;
interface Inter<T>//泛型定义在接口上
{
	void show(T t);
}
class InterImpl<T> implements Inter<T>
{
	public void show(T t)
	{
		System.out.println("show :"+t);
	}
}
class GenericDemo5 
{
	public static void main(String[] args) 
	{
		InterImpl<Integer> i = new InterImpl<Integer>();
		i.show(4);//调用show方法
	}
}

泛型的限定:

? 通配符。也可以理解为占位符。

泛型的限定;

? extends E: 可以接收E类型或者E的子类型。上限。

? super E:可以接收E类型或者E的父类型。下限

代码实现:

import java.util.*;
class  GenericDemo6
{
	public static void main(String[] args) 
	{
		ArrayList<Person> al = new ArrayList<Person>();
		al.add(new Person("abc1"));
		al.add(new Person("abc2"));
		al.add(new Person("abc3"));
		//printColl(al);
		ArrayList<Student> al1 = new ArrayList<Student>();
		al1.add(new Student("abc--1"));
		al1.add(new Student("abc--2"));
		al1.add(new Student("abc--3"));
		printColl(al1);  
	}
	public static void printColl(Collection<? extends Person> al)//可以接收Person以及它的子类
	{
		Iterator<? extends Person> it = al.iterator();//可以接收Person以及它的子类
		while(it.hasNext())
		{
			System.out.println(it.next().getName());
		}
	}
}
class Person//定义Person类并初始化
{
	private String name;
	Person(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return name;
	}
}
class Student extends Person//定义Student类并继承Person类
{
	Student(String name)
	{
		super(name);
	}
}
class Comp implements Comparator<Person>//新建类实现Comparator,并对compare方法进行复写
{
	public int compare(Person s1,Person s2)
	{
			return s1.getName().compareTo(s2.getName());
	}
}

Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。

       1,添加。

              put(K key, V value)

              putAll(Map<? extends K,? extends V> m)

       2,删除。

              clear()

              remove(Object key)

       3,判断。

              containsValue(Object value)

              containsKey(Object key)

              isEmpty()

       4,获取。

              get(Object key)

              size()

              values()

 

              entrySet()返回此映射中包含的映射关系的Set视图

              keySet()返回此映射中包含的键Set视图

 

Map

       |--Hashtable:底层是哈希表数据结构,不可以存入nullnull值。该集合是线程同步的。jdk1.0.效率低。

       |--HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。

       |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

Set底层就是使用了Map集合

import java.util.*;
class  MapDemo
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		//添加元素,如果出现添加时,有同的键。那么后添加的值会覆盖原有键对应值。
		//并put方法会返回被覆盖的值。
		System.out.println("put:"+map.put("01","zhangsan1"));
		System.out.println("put:"+map.put("01","wnagwu"));//键相同,wangwu会覆盖zhangsan1
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		System.out.println("containsKey:"+map.containsKey("02"));//判断是否存在02键对应的数据
		//System.out.println("remove:"+map.remove("02"));//将02键对应的数据移除
		System.out.println("get:"+map.get("02"));//获取02键对应的数据
		map.put("04",null);//将04键对应的null数据存入
		System.out.println("get:"+map.get("04"));
		//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
		//获取map集合中所有的值。
		Collection<String> coll = map.values();
		System.out.println(coll);
		System.out.println(map);
	}
}

map集合的两种取出方式:

1Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。

       所以可以用迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。

       Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。

2Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry                      

Entry其实就是Map中的一个static内部接口。

为什么要定义在内部呢?

因为只有有了Map集合,有了键值对,才会有键值的映射关系。关系属于Map集合中的一个内部事物,而且该事物在直接访问Map集合中的元素。

import java.util.*;
class MapDemo2 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();//建立集合
		map.put("02","zhangsan2");//向集合中传入数据
		map.put("03","zhangsan3");
		map.put("01","zhangsan1");
		map.put("04","zhangsan4");
		//将Map集合中的映射关系取出。存入到Set集合中。
		Set<Map.Entry<String,String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String,String>> it = entrySet.iterator();
		while(it.hasNext())
		{
			Map.Entry<String,String> me = it.next();
			String key = me.getKey();
			String value = me.getValue();
			System.out.println(key+":"+value);
		}
		/*
		//先获取map集合的所有键的Set集合,keySet();
		Set<String> keySet = map.keySet();
		//有了Set集合。就可以获取其迭代器。
		Iterator<String> it = keySet.iterator();
		while(it.hasNext())
		{
			String key = it.next();
			//有了键可以通过map集合的get方法获取其对应的值。
			String value  = map.get(key);
			System.out.println("key:"+key+",value:"+value);
		}
		*/
	}
}

map扩展知识。

map集合被使用是因为具备映射关系。

"yureban"   Student("01" "zhangsan");

"yureban" Student("02" "lisi");

"jiuyeban" "01" "wangwu";

"jiuyeban" "02" "zhaoliu";

一个学校有多个教室。每一个教室都有名称。

import java.util.*;
class Student//建立学生类
{
	private String id;
	private String name;
	Student(String id,String name)
	{
		this.id = id;
		this.name = name;
	}
	public String toString()
	{
		return id+":::"+name;
	}
}
class  MapDemo3
{
	public static void demo()
	{
		HashMap<String,List<Student>> czbk = new HashMap<String,List<Student>>();//创建集合czbk
		List<Student> reyu = new ArrayList<Student>();//创建reyu集合
		List<Student> jiuye = new ArrayList<Student>();//创建jiuye集合
		czbk.put("yureban",reyu);//将reyu集合放入czbk中
		czbk.put("jiuyeban",jiuye);将jiuye集合放入czbk中
		reyu.add(new Student("01","zhagnsa"));//传入学生参数
		reyu.add(new Student("04","wangwu"));
		jiuye.add(new Student("01","zhouqi"));
		jiuye.add(new Student("02","zhaoli"));
		Iterator<String> it = czbk.keySet().iterator();//使用迭代器对czbk进行迭代
		while(it.hasNext())
		{
			String roomName = it.next();
			List<Student> room = czbk.get(roomName);
			System.out.println(roomName);
			getInfos(room);
		}
	}
	public static void getInfos(List<Student> list)
	{
		Iterator<Student> it = list.iterator();//对学生参数进行迭代
		while(it.hasNext())
		{
			Student s = it.next();
			System.out.println(s);
		}
	}
	public static void main(String[] args) 
	{
		 demo();
	}
}

练习:

"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。希望打印结果:a(1)c(2).....

 

通过结果发现,每一个字母都有对应的次数。说明字母和次数之间都有映射关系。当发现有映射关系时,可以选择map集合。因为map集合中存放就是映射关系。

什么时候使用map集合呢?当数据之间存在这映射关系时,就要先想map集合。

思路:

1,将字符串转换成字符数组。因为要对每一个字母进行操作。

2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。

3,遍历字符数组。

       将每一个字母作为键去查map集合。

       如果返回null,将该字母和1存入到map集合中。

       如果返回不是null,说明该字母在map集合已经存在并有对应次数。

       那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。

4,将map集合中的数据变成指定的字符串形式返回。

代码实现:

import java.util.*;
class  MapTest3
{
	public static void main(String[] args) 
	{
		String s= charCount("ak+abAf1c,dCkaAbc-defa");//传入字符串
		System.out.println(s);
	}
	public static String charCount(String str)
	{
		char[] chs = str.toCharArray();//将字符串转成字符数组
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();//建立TreeMap集合
		int count = 0;
		for(int x=0; x<chs.length; x++)//对字符数组进行遍历
		{
			if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z'))//如果遍历到的元素不是字母,则继续循环否则将字母出现次数记录
			continue;
			Integer value = tm.get(chs[x]);
			if(value!=null)
				count = value;
			count++;
			tm.put(chs[x],count);//直接往集合中存储字符和数字,为什么可以,因为自动装箱。
			count = 0;//将count还原
		}
		StringBuilder sb = new StringBuilder();
		Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();//建立entrySet集合
		Iterator<Map.Entry<Character,Integer>>  it = entrySet.iterator();//对集合进行迭代
		while(it.hasNext())
		{
			Map.Entry<Character,Integer> me = it.next();
			Character ch = me.getKey();//获得键
			Integer value = me.getValue();//获得键对应的数据
			sb.append(ch+"("+value+")");
		}
		return sb.toString();//将新的字符数组转成字符串
	}
}

集合框架的工具类。

Collections:集合框架的工具类。里面定义的都是静态方法。

CollectionsCollection有什么区别?

Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。

              它有两个常用的子接口,

              List:对元素都有定义索引。有序的。可以重复元素。

              Set:不可以重复元素。无序。

Collections是集合框架中的一个工具类。该类中的方法都是静态的,提供的方法中有可以对list集合进行排序,二分查找等方法。通常常用的集合都是线程不安全的,因为要提高效率。如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

import java.util.*;
class  CollectionsDemo
{
	public static void main(String[] args) 
	{
		sortDemo();
	}
	public static void binarySearchDemo()
	{
		List<String> list = new ArrayList<String>();//建立集合
		list.add("abcd");//向集合中添加元素
		list.add("aaa");
		list.add("zz");
		list.add("kkkkk");
		list.add("qq");
		list.add("z");
		Collections.sort(list,new StrLenComparator());//按照自定义的排序方式对集合排序
		sop(list);//将结果打印
		int index = halfSearch(list,"aaaa",new StrLenComparator());//调用二分查找方法,在集合中查找数据aaaa
		sop("index="+index);
	}
	public static int halfSearch(List<String> list,String key)//二分查找
	{
		int max,min,mid;
		max = list.size()-1;
		min = 0;
		while(min<=max)
		{
			mid = (max+min)>>1;//  /2;
			String str = list.get(mid);
			int num = str.compareTo(key);
			if(num>0)
				max = mid -1;
			else if(num<0)
				min = mid + 1;
			else
				return mid;
		}
		return -min-1;//返回-(应该所在位置)-1
	}
	public static void maxDemo()//获取集合中最大数据
	{
		List<String> list = new ArrayList<String>();
		list.add("abcd");
		list.add("aaa");
		list.add("zz");
		list.add("kkkkk");
		list.add("qq");
		list.add("z");
		Collections.sort(list);
		sop(list);
		String max = Collections.max(list/*,new StrLenComparator()*/);
		sop("max="+max);
	}
	public static void sortDemo()//将集合进行排序
	{
		List<String> list = new ArrayList<String>();
		list.add("abcd");
		list.add("aaa");
		list.add("zz");
		list.add("kkkkk");
		list.add("qq");
		list.add("z");
		sop(list);
		//Collections.sort(list);
		Collections.sort(list,new StrLenComparator());
		//Collections.swap(list,1,2);
		sop(list);
			}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
class StrLenComparator implements Comparator<String>//将集合中元素按长度进行比较
{
	public int compare(String s1,String s2)
	{
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()<s2.length())
			return -1;
		return s1.compareTo(s2);
	}
}

将数组转变成集合:

Arrays:用于操作数组的工具类。里面都是静态方法。

asList:将数组变成list集合

把数组变成list集合有什么好处?

可以使用集合的思想和方法来操作数组中的元素。

注意:将数组变成集合,不可以使用集合的增删方法。因为数组的长度是固定。如果使用增删方法,那么会反生UnsupportedOperationException异常。

如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。

如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

import java.util.*;
class  ArraysDemo
{
	public static void main(String[] args) 
	{
		int[] arr = {2,4,5};//新建数组
		System.out.println(Arrays.toString(arr));//将数组变成字符串
		String[] arr = {"abc","cc","kkkk"};//新建字符数组
		List<String> list = Arrays.asList(arr);//建立集合,并将字符数组传入
		//sop("contains:"+list.contains("cc"));//判断集合中是否包含cc
		//list.add("qq");//不可以进行增删,会出现UnsupportedOperationException异常
		//sop(list);
		Integer[] nums = {2,4,5};//将基本类型数据转成集合
		List<Integer> li = Arrays.asList(nums);
		sop(li);
	}
	public static boolean myContains(String[] arr,String key)
	{
		for(int x=0;x<arr.length; x++)//遍历字符数组,判断是否含有key
		{
			if(arr[x].equals(key))
				return true;
		}
		return false;
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

集合变数组。

Collection接口中的toArray方法。

1,指定类型的数组到底要定义多长呢?

当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。当指定类型的数组长度大于了集合的size,就不会新创建数组,而是使用传递进来的数组。所以创建一个刚刚好的数组最优。

2,为什么要将集合变数组?

为了限定对元素的操作。不需要进行增删了。

import java.util.*;
class  CollectionToArray
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();//新建集合
		al.add("abc1");//向集合中传入数据
		al.add("abc2");
		al.add("abc3");
		String[] arr = al.toArray(new String[al.size()]);//将集合变成数组
		System.out.println(Arrays.toString(arr));//将数组变成字符串打印
	}
}

高级for循环

格式:

for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)

{

}

对集合进行遍历。

只能获取集合元素。但是不能对集合进行操作。

迭代器除了遍历,还可以进行remove集合中元素的动作。

如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

传统for和高级for有什么区别呢?

高级for有一个局限性。必须有被遍历的目标。

建议在遍历数组的时候,还是希望是用传统for,因为传统for可以定义角标。

import java.util.*;
class ForEachDemo 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();//建立集合
		al.add("abc1");//向集合中传入数据
		al.add("abc2");
		al.add("abc3");
		for(String s : al)//用高级for循环对集合进行遍历
		{
			//s = "kk";//不能对集合进行操作
			System.out.println(s);
		}
		int[] arr = {3,5,1};
		for(int x=0; x<arr.length; x++)//用传统for循环进行打印
		{
			System.out.println(arr[x]);
		}
		for(int i : arr)//用高级for循环进行遍历打印
		{
			System.out.println("i:"+i);
		}
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(1,"a");
		hm.put(2,"b");
		hm.put(3,"c");
		Set<Integer> keySet = hm.keySet();
		for(Integer i : keySet)//高级for循环对集合进行遍历
		{
			System.out.println(i+"::"+hm.get(i));
		}
//		Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
//		for(Map.Entry<Integer,String> me : entrySet)
		for(Map.Entry<Integer,String> me : hm.entrySet())//将上两句合为一句
		{
			System.out.println(me.getKey()+"------"+me.getValue());
		}
	}
}

JDK1.5版本出现的新特性。

方法的可变参数。

在使用时注意:可变参数一定要定义在参数列表最后面。

import java.util.*;
class  ParamMethodDemo
{
	public static void main(String[] args) 
	{
		int[] arr = {3,4};//这样每次都要新定义数组
		show(arr);
		/*
		可变参数。
		其实就是上一种数组参数的简写形式。
		不用每一次都手动的建立数组对象。
		只要将要操作的元素作为参数传递即可。
		隐式将这些参数封装成了数组。
		*/
		show("haha",2,3,4,5,6);
		show(2,3,4,5,6,4,2,35,9,"heh");
		}
	public static void show(String str,int... arr)// 可变参数一定要定义在参数列表最后面。
	{
		System.out.println(arr.length);
	}
}

StaticImport  静态导入。

当类名重名时,需要指定具体的包名。当方法重名是,指定具备所属的对象或者类。

import java.util.*;
import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。
import static java.util.Collections.*;
import static  java.lang.System.*;//导入了System类中所有静态成员。
class  StaticImport //extends Object
{
	public static void main(String[] args) 
	{
		out.println("haha");//因为导入了System类中所有静态成员,所以System可以省略
		int[] arr = {3,1,5};
		sort(arr);
		int index = binarySearch(arr,1);//省略了Collections
		out.println(Arrays.toString(arr));
		System.out.println("Index="+index);
		ArrayList al = new ArrayList();
		al.add(1);
		al.add(3);
		al.add(2);
		out.println(al);
		sort(al);
		out.println(al);
	}
}























 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值