java 类集框架 学习笔记

类集框架

一、Collection 集合接口

当前主要分类两个子接口,允许重复的List接口和不允许重复的Set接口

1. List接口

import java.util.List;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        List<String> all = List.of("bob","john","tom");
        Object[] result = all.toArray();
        for (Object t:result){
            System.out.println(t+"、");
        }
    }
}

使用List接口进行开发时,主要使用其子类进行实例化,常用子类有ArrayList, Vector, LinkedList

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

public class javaDemo{
    public static void main(String[] args) throws Exception{
        List<String> all = new ArrayList<>();
        all.add("bob");
        all.add("tom");
        all.add("john");
        System.out.println(all.get(1));
        System.out.println(all);
        all.remove("bob"); // 删除bob元素
        all.isEmpty(); // 集合是否为空
        all.contains("bob"); // 是否包含bob元素
        all.size(); // 集合长度
        all.forEach((str)->{ // 打印方法
            System.out.println(str+"、");
        });
    }
}

上面程序实现了打印,但是是利用每个类中的toString()方法实现的,也就是需要类中实现有toString方法,对自定义的类不利,因为自定义类中未必实现了toString()

ArrayList保存自定义类对象

由于String是一个完善的类,因此在类集操作时可以保存任意类型的数据,这也就包括了开发者自己定义的类。为了保证集合中的contains()remove()两个方法的正确执行,需要覆写equals()方法

import java.util.ArrayList;
import java.util.List;
class Member{
    private String name;
    private int age;

    public Member(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o){
            return true;
        }
        if(o == null){
            return false;
        }
        if (!(o instanceof Member)){
            return false;
        }
        Member mem = (Member) o;

        return this.name.equals(mem.name) && this.age == mem.age;

    }
    public String toString(){
        return "姓名:"+ this.name+"、年龄:"+this.age;
    }
}
public class javaDemo{
    public static void main(String[] args) throws Exception{
        List<Member> all = new ArrayList<Member>();
        all.add(new Member("BOB",13));
        all.add(new Member("TOM", 15));
        all.add(new Member("JOHN", 22));
        all.remove(new Member("TOM", 15));
        all.forEach(System.out::println);

    }
}

ArrayList使用了数组Array保存数据,如果数据超过限度,该类自动进行扩展,将旧数组中的数据复制到新数组中,最大限制为private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8

如果频繁进行数组的扩展,会造成大量的内存垃圾,因此使用该类的时候,需要对集合大小进行合理的估算,不要频繁改动

无参构造:public ArrayList(),使用空数组进行初始化,第一次使用时开辟长度为10的空间

有参构造:public ArrayList(int initialCapacity),开辟空间,为0则使用无参构造,为负数,抛出异常

1.2 LinkedList

实现方法与ArrayList一致,但是其是建立在链表形式的List接口标准,进行添加元素时,不像ArrayList那样频繁的进行复制开辟新数组,而是可以直接以O(1)的复杂度插入数据

但在根据索引获取元素的时候,复杂度为O(n),比Array的O(1)差了许多

1.3 Vector

和ArrayList类实现一致,唯一的区别是Vector的操作方法都用了synchronized进行同步处理,因此是线程安全的,但是性能会降低,所以Vector可以用在多线程并发访问时

2 Set接口

如果调用Set.of()方法时出现了重复元素,会抛出异常

其有两个常用子类HashSetTreeSet

2.1 HashSet

不允许保存重复元素,且以散列(无序)方式进行存储

import java.util.HashSet;
import java.util.Set;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Set<String> all = new HashSet<>();
        all.add("bob");
        all.add("tom");
        all.add("john");
        System.out.println(all);
    }
}

输出数据以无序格式存放,不会按照添加顺序打印出来,且重复元素会去除

2.1.1 LinkedHashSet
import java.util.LinkedHashSet;
import java.util.Set;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Set<String> all = new LinkedHashSet<>();
        all.add("bob");
        all.add("tom");
        all.add("tom");
        all.add("john");
        System.out.println(all);
    }
}

HashSeet的问题在于无序存储,所以LinkedHashSet实现了基于链表的数据存储,保留了顺序,且不允许重复元素

2.2 TreeSet

可以使集合保存的数据进行有序排列

import java.util.Set;
import java.util.TreeSet;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Set<String> all = new TreeSet<>();
        all.add("bibibi");
        all.add("tom");
        all.add("tom");
        all.add("john");
        System.out.println(all);
    }
}
输出:[bibibi, john, tom]

TreeSet类实现有序数据存储是根据Comparable接口实现的,并且根据接口中的compareTo()方法来判断重复元素,所以使用TreeSet类存储自定义类对象的时候,必须实现Comparable接口,覆写comareTo方法时需要进行类中全部属性的比较,否则会出现部分属性相同时被误判为同一对象,导致重复元素判断失败

import java.util.Set;
import java.util.TreeSet;

class Member implements Comparable<Member>{
    private String name;
    private int age;

    public Member(String name, int age){
        this.name = name;
        this.age = age;
    }
//  覆写comareTo方法,并且比较所有的属性是否相同
    @Override
    public int compareTo(Member mem){
        if (this.age > mem.age){
            return -1;
        } else if(this.age < mem.age){
            return 1;
        } else{
            return this.name.compareTo(mem.name);
        }
    }
    
    public String toString(){
        return "姓名:"+ this.name+"、年龄:"+this.age;
    }
}
public class javaDemo{
    public static void main(String[] args) throws Exception{
        Set<Member> all = new TreeSet<Member>();
        all.add(new Member("BOB",13));
        all.add(new Member("TOM", 15));
        all.add(new Member("JOHN", 22));
//        all.remove(new Member("TOM", 15));
        all.forEach(System.out::println);
    }
}
2.2.1 重复元素消除(待处理)

二、Collection集合输出

collection接口提供了toArray方法将集合保存的数据转为对象数组返回,用户可以利用循环进行读取,但性能不佳。在类集框架中提供了4种方式:Iterator, ListIterator, Enmueration, foreach

1. Iterator

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Set<String> all = new TreeSet<>();
        all.add("bibibi");
        all.add("tom");
        all.add("tom");
        all.add("john");
        Iterator<String > iter = all.iterator();
        while (iter.hasNext()){ //判断是否有下一个值
            String str = iter.next(); // 接受任意类型的数据
            System.out.println(str+"、");
        }
    }
}

迭代输出中的remove()方法,不要使用Collection中提供的remove方法,而应该使用iterator.remove()方法,否则会出现并发访问异常java.util.ConcurrentModificationException

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Set<String> all = new TreeSet<>();
        all.add("bibibi");
        all.add("tom");
        all.add("tom");
        all.add("john");
        Iterator<String > iter = all.iterator();
        while (iter.hasNext()){
            String str = iter.next();
            if (str.equals("john")){
                iter.remove();
            }else {
            System.out.println(str+"、");}
        }
    }
}

2. ListIterator

Iterator实现了单向迭代操作,而ListIterator则提供了双向迭代操作,此接口为Iterator的子接口,仅能对List类进行实例化,而Iterator可以对Collection进行实例化

该类没有提供remove方法

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        List<String> all = new ArrayList<>();
        all.add("helen");
        all.add("tom");
        all.add("john");
        ListIterator<String > iter = all.listIterator();
        while (iter.hasNext()){
            String str = iter.next();
            System.out.println(str+"、");
        }
        while (iter.hasPrevious()){
            String pre = iter.previous();
            System.out.println(pre+"、");
        }
    }
}

使用双向迭代的时候,必须先从前向后迭代,再从后向前迭代

3. Enmueration

该类主要针对Vector类的输出进行处理,其没有提供remove方法

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Vector<String> all = new Vector<>(); // 只使用Vector类
        all.add("helen");
        all.add("tom");
        all.add("john");
        Enumeration<String > enu = all.elements();
        while (enu.hasMoreElements()){
            String str = enu.nextElement();
            System.out.println(str+"、");
        }
    }
}

3. foreach

使用foreach实现输出

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        List<String> all = new ArrayList<>();
        all.add("helen");
        all.add("tom");
        all.add("john");
        for (String s: all){
            System.out.println(s);
        }
    }
}

实现自定义类的输出,需要实现Iterable接口,这样就鞥呢利用foreach实现输出操作

三、Map集合

存储结构为(key == value)

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Map<String, Integer> map = Map.of("one",1, "two",2); // map的格式为<K, V>
        System.out.println(map);
    }
}

这种设计方法比较死板,实际使用中主要使用其子类进行实例化,常见的有HashMap、LinkedHashMap、HashTable、TreeMap

1. HashMap

基于散列形式实现Map集合

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Map<String, Integer> map = new HashMap<>();
        map.put("funny", 2);
        map.put("tom",12);
        map.put("tom",222); // key重复则会覆盖前值
        map.put("scc",null);
        map.put(null, 2);
        System.out.println(map.get("funny"));
        System.out.println(map.get(null)); // 即便key为null,也会输出其key=2
        System.out.println(map.get("tom"));
    }
}

Collection设置完内容的目的是输出,Map的目的是查找

2. LinkedHashMap

基于链表的形式实现了Map集合,实现了有序集合

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Map<String, Integer> map = new LinkedHashMap<>();
        map.put("funny", 2);
        map.put("tom",12);
        map.put("scc",null);
        map.put(null, 2);
        System.out.println(map);
    }
}

3. Hashtable

HashMap允许实现异步操作(非线程安全),HashMap允许保存null数据

Hashtable属于同步操作(线程安全),不允许保存null数据,否则会抛出NullPointerException

4. TreeMap

同样使用Comparable接口实现内容的有序存储

String类中实现了Comparable接口,所以可以进行排序

import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Map<String, Integer> map = new TreeMap<>();
        map.put("funny", 2);
        map.put("tom",12);
        map.put("clarie",24);
        System.out.println(map)
    }
}

5. Map.Entry内部接口

import java.util.*;

public class javaDemo{
    public static void main(String[] args) {
        Map.Entry<String, Integer> entry = Map.entry("ONE", 1);
        System.out.println(entry.getKey());
        System.out.println(entry.getValue());
        System.out.println(entry.getClass().getName());
    }
}
输出:
ONE
1
java.util.KeyValueHolder

6. Iterator输出Map集合

要输出Map集合内容,Map接口中保存的数据是多个Map.Entry接口封装的二元偶对象,所以采用下面步骤实现Map集合的迭代输出

  1. 使用Map接口中的enrtySet()方法,将Map集合变为Set结合
  2. 取得了Set集合的接口后,可以利用Iterator()方法取得Iterator的实例化对象
  3. 使用Iterator迭代找到每一个Mao.Entry对象,并进行key和value的分离

Map集合中的都是[ Map.Entry,Map.Entry,Map.Entry ]

Collection集合中都是[ 对象,对象,对象 ]

import java.util.*;

public class javaDemo{
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("one", 1);
        map.put("two" ,2);
        Set<Map.Entry<String, Integer>> set = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iter = set.iterator();
        while (iter.hasNext()){// 使用iterator接口实现输出
            Map.Entry<String, Integer> me = iter.next(); // 使用类型为Map.Entry的me变量存储iter的输出
            System.out.println(me.getKey()+" == "+me.getValue());
        }
        for (Map.Entry<String, Integer> entry:set){// 使用foreach输出
            System.out.println(entry.getKey()+" == "+entry.getValue());
        }
    }
}

7. 自定义key类型

覆写hashCode()和equals()方法

四、Stack栈

栈是有序的数据结构,采用先进后出的存储模式,开发者只能进行栈顶操作,主要有入栈和出栈两种操作

import java.util.*;

public class javaDemo{
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        stack.push("A"); // 入栈
        stack.push("B");
        stack.push("C");
        System.out.println(stack.peek()); // 查看栈顶 输出:C
        System.out.println(stack.search("B")); // 输出:2
        System.out.println(stack.pop()); // 出栈并删除栈顶元素  输出:C
        System.out.println(stack.pop()); // 输出:B
    }
}

五、Queue队列

import java.util.*;

public class javaDemo{
    public static void main(String[] args) {
        Queue<String> queue = new PriorityQueue<>();
        queue.add("A");
        queue.add("B");// 添加元素
        queue.offer("C");// 添加元素
        System.out.println(queue.peek()); // 查看队首 输出 A
        System.out.println(queue.poll()); // 删除元素并输出
        System.out.println(queue.poll());
    }
}

为了实现能在队首和队尾操作元素的,java实现了Queue的子类Deque

import java.util.*;

public class javaDemo{
    public static void main(String[] args) {
        Deque<String> deque = new LinkedList<>();
        deque.addLast("A"); // 添加到队尾
        deque.addFirst("B"); // 添加到队首
        deque.offerFirst("C"); // 添加到队首
        System.out.println(deque.peekFirst()); // 查看队首元素
        System.out.println(deque.removeFirst()); // 删除队首元素
        System.out.println(deque.pollFirst()); // 删除队首元素并输出
        System.out.println(deque.pollLast()); // 删除队尾元素并输出
    }
}

六、Properties属性操作

该类主要用来处理字符串的输入输出,实现属性内容的传输操作。虽然是Hashtable的子集,但是该类只能处理字符串

import java.util.*;

public class javaDemo{
    public static void main(String[] args) {
        Properties prop = new Properties();
        prop.setProperty("one", "1");
        prop.setProperty("two", "2");
        System.out.println(prop.getProperty("one"));
        System.out.println(prop.getProperty("THREE", "not found")); // 不存在这个key,返回not found
    }
}
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Properties prop = new Properties();
        prop.setProperty("one", "1");
        prop.setProperty("two", "2");
        prop.store(new FileOutputStream(new File("info.properties")), "Very Import URL");
    }
}
import java.io.File;
import java.io.FileInputStream;
import java.util.*;

public class javaDemo{
    public static void main(String[] args) throws Exception{
        Properties prop = new Properties();
        prop.setProperty("one", "1");
        prop.setProperty("two", "2");
        prop.load(new FileInputStream(new File("info.properties"))); // 读取输入流的属性内容
        System.out.println(prop.getProperty("one"));
    }
}

可以使用Properties类读取属性文件将属性内容加载到程序中进行属性查询操作

七、Collections工具类

1. Collections

一些Collection未提供的方法在Collections类中提供

import java.util.*;

public class javaDemo{
    public static void main(String[] args){
        List<String> all = new ArrayList<>();
        Collections.addAll(all, "Hello", "Helen","Hey!");
        Collections.reverse(all);
        System.out.println(Collections.binarySearch(all, "Helen"));
    }
}
import java.util.*;
import java.util.stream.Stream;

public class javaDemo{
    public static void main(String[] args){
        List<String> all = new ArrayList<>();
        Collections.addAll(all, "Hello", "Helen","Hey!");
        Stream<String> stream = all.stream();
        System.out.println(stream.filter((ele)-> ele.toLowerCase().contains("h")).count());
    }
}

2. MapReduce

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Order { 														// 订单信息
    private String name; 												// 商品名称
    private double price; 											// 商品单价
    private int amount; 												// 商品数量
    public Order(String name, double price, int amount) {
        this.name = name;
        this.price = price;
        this.amount = amount;
    }
    // setter方法、无参构造略 ...
    public int getAmount() {
        return amount;
    }
    public String getName() {
        return name;
    }
    public double getPrice() {
        return price;
    }
}

public class javaDemo{
    public static void main(String[] args) throws Exception{
        // 如果要想使用Stream进行分析处理,则一定要将全部要分析的数据保存在集合之中
        List<Order> all = new ArrayList<Order>();						// List集合
        all.add(new Order("狗熊娃娃", 9.9, 10));						// 数据添加
        all.add(new Order("MLDN-极限IT", 2980.0, 3));					// 数据添加
        all.add(new Order("MLDN系列教材", 8987.9, 8));					// 数据添加
        all.add(new Order("MLDN定制笔记本", 2.9, 800));					// 数据添加
        all.add(new Order("MLDN定制鼠标垫", 0.9, 138));					// 数据添加
        DoubleSummaryStatistics stat = all.stream().filter((ele)-> ele.getName().toLowerCase().contains("mldn")).mapToDouble((order) ->
                order.getAmount()*order.getPrice()).summaryStatistics();
        System.out.println(stat.getMax());
        System.out.println(stat.getSum());
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值