集合
- 集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
- 集合里面存储的都是引用类型,那八大基本类型不可以存储(若想存整数类型,虽然不能使用int但可以使用int的包装类型integer,其他基本类型的存储类似)
集合类体系结构:
- 单列:Collection[接口]—在Java.util包下,使用的时候需要导包
- List[接口]:可重复 可索引
- ArrayList[实现类]——-数组
- LinkedList[实现类]———双向链表
- Set[接口]:不可重复
- HashSet[实现类]
- TreeSet[实现类]
- List[接口]:可重复 可索引
- 双列:Map[接口]
- HashMap[实现类]
Collection常用方法
//如果要使用Collection,不能直接实例化,但可以使用多态的方法,创建ArrayList对象
Collection<String> c = new ArrayList<String>();
c.add("Hello");
c.add("World");
System.out.println(c);
// [Hello, World]
------------------------------------------------------------------------------------------
常用方法: boolean add()添加元素[返回值永远是 true] boolean remove()从集合中删除指定元素 void clear()从集合中清空元素 boolean contains()判断集合中是否存在某些元素 boolean isEmpty()判断集合是否为空 int size()求集合的长度
Collection元素的遍历,使用迭代器
Collection<String> c = new ArrayList<String>();
c.add("Hello");
c.add("World");
c.add("Java");
Iterator<String> it = c.iterator();//创建迭代器
while (it.hasNext()){//判断下一个元素是否为空
String s=it.next();//获得下一个元素
System.out.print(s+" ");
}
System.out.println();
List
List集合的特点
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可以重复
List集合常用的方法
void add(int index,E element)//在指定位置插入元素
E remove(int index)//删除指定索引处的元素,返回被删除的元素
E set(int index,E element)//修改指定索引处的元素,返回被修改的元素
E get(int index)//返回指定索引处的元素
哈希值
- 是JDK根据对象的地址或者字符串或者地址算出来的int类型的数值
- Object类中有[hashCode]方法可以获得对象的哈希值
- 对象哈希值的特点
- 同一对象多次调用HashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值不同,而重写HashCode()方法,可以实现不同对象哈希值相同
HashSet集合的特点
- 底层数据结构是哈希表
- 对集合的迭代顺序不做任何保证,不保证存储和取出元素的顺序一致
- 没有带索引的方法,不能通过普通的for()循环遍历
- 由于是Set的集合,所以是不包含重复元素的集合,但是要自己在自己创建的类中去自己实现equals和HashCode
确保元素唯一性的源码分析
哈希表的存储方式示意图
LinkedHashSet
- 哈希表和链表实现的Set接口,具有可预测的迭代顺序
- 由链表保证元素有序---->存储和取出的次序一致
- 由哈希表保证元素的唯一,没有重复的元素
TreeSet
- 由于是Set集合,所以不包含重复元素
- 没有带索引方法,不能使用不同for循环遍历
- 元素有序,【这个的有序不是指存储和取出的有序,而是根据构造方法而定的规则】
- TreeSet() 若是无参构造方法,根据元素自然排序[对整形来说是升序]进行排序
- TreeSet(Comparator comparator):根据指定的比较器进行排序
存储学生类 按年龄升序 年龄相同按字母顺序排
要求使用无参构造方法
-
要求:使用TreeSet的无参构造方法,假如存储一个学生类信息(姓名,年龄), 首先按年龄升序排序,若年龄相同,则按姓名首字母的先后顺序排序
public class Teacher implements Comparable<Teacher> { //这里需要对接一个接口 接口的参数应该为这个类名 // @Override public int compareTo(Teacher s) { int num=this.age-s.age;//要是升序的话就使用 [this. - s.] 降序的话使用[s. - this. ] int num2=num==0?s.name.compareTo(this.name):num; //这里如果年龄相等,则比较姓名,实现升序或降序还是同上述讲的一样:升序 this在前,降序s在前 return num2; } }
要求使用带参构造方法
-
题目同上,但是要求使用带参构造方法实现,即**使用比较器实现**
TreeSet<Teacher> s = new TreeSet<>(new Comparator<Teacher>() { // @Override public int compare(Teacher s1, Teacher s2) { int num=s1.getAge()-s2.getAge();//注意,属性因为私有化了,所以不可以直接.去调用,而应该使用get()方法调用 int num2=num==0?s1.getName().compareTo(s2.getName()):num; return num2; } });
泛型
泛型类
//泛型类的创建
public class Geners<T> {
private T t;
public Geners(T t) {
this.t = t;
}
public Geners() {
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
泛型方法(简单创建和调用)
public class Geners {
public<T> void show(T t){
System.out.println(t);
}
}
----------------------------------------------------------------------
Geners s = new Geners();
s.show("Cx_330");
s.show(30);
s.show(12.33);
s.show(true);
泛型接口
- 创建简单实现
//泛型接口创建
public interface Generic <T>{
void show(T t);
}
----------------------------------------------------------------------
//泛型类对接接口的创建
public class Geners<T> implements Generic<T> {
//@Override
public void show(T t) {
System.out.println(t);
}
}
----------------------------------------------------------------------
//简单调用接口
Generic<String> s=new Geners<String>();
s.show("Cx330");
Generic<Integer> s1=new Geners<Integer>();
s1.show(30);
类型通配符
- 创建格式 extends/super
List<?> l1=new ArrayList<Object>();
List<?> l2=new ArrayList<Number>();
List<?> l3=new ArrayList<Integer>();
List<? extends Number>l4=new ArrayList<Number>();
List<? extends Number>l5=new ArrayList<Integer>();
List<? super Number>l6=new ArrayList<Object>();
List<? super Number>l7=new ArrayList<Number>();
可变参数
// 方法重载 求sum()
public class Test {
public static void main(String[] args) {
System.out.println(sum(10));
System.out.println(sum(10,20));
System.out.println(sum(10,20,30));
System.out.println(sum(10,20,30,40,50));
}
public static int sum(int...a){
//注意
//1:这里的变量a其实是一个数组
//2:如果一个方法有多个参数包含可变参数,则这个可变参数一定要放到最后面
int sum=0;
for (int i : a) {
sum+=i;
}
return sum;
}
}
Map
遍历方法一[增强for&&键找值]
Map<String, String> s = new HashMap<>();
s.put("001","灰灰");
s.put("002","可可");
s.put("003","小小");
Set<String> key=s.keySet();//获得键的集合 Set创建集合
for(String s1:key){
String val=s.get(s1);//获得每个值是通过map.get(键)的返回值获得的
System.out.println(s1+","+val);
- 遍历方法二[增强for&&通过键值对对象找键和值]
Map<String, String> s = new HashMap<>();
s.put("001","灰灰");
s.put("002","可可");
s.put("003","小小");
Set<Map.Entry<String,String>> entries=s.entrySet();//获得键值对的集合
for(Map.Entry<String,String>me:entries){
String key=me.getKey();
String val=me.getValue();
System.out.println(key+","+val);
}
小测试:求字符串中每个字符出现的次数
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
String s=scanner.next();
HashMap<Character,Integer> hm=new HashMap<Character,Integer>();
for (int i = 0; i <s.length() ; i++) {
Character ch=s.charAt(i);
Integer in=hm.get(ch);
if(in==null){
hm.put(ch,1);
}else {
in++;
hm.put(ch,in);
}
}
Set<Character> key=hm.keySet();
StringBuilder sb = new StringBuilder();
for(Character cha:key){
Integer in=hm.get(cha);
sb.append(cha).append("(").append(in).append(")");
}
String resule=sb.toString();
System.out.println(resule);
Collections
- 是针对集合操作的工具类
List<Integer> list=new ArrayList<>();
list.add(10);
list.add(30);
list.add(9);
Collections.sort(list); //使用格式
Collections.reverse(list);//使用格式
Collections.shuffle(list);//使用格式
System.out.println(list);