11持有对象-Java编程思想


Java提供一套相当完整的容器类来存储数量不确定的对象。集合类:list,set.queue,map。通过使用泛型,可以在编译器防止将错误类型的对象放置到容器中去,在取出的时候也会帮忙转型。

Collection,一个独立元素序列。List按照插入的顺序保存元素,set不能有重复的元素,Queue按照队列的规则确定对象顺序。

Map键值对,允许用键来找值。

HashSet\TreeSet\LinkedHashSet都是Set类型。HashSet是最快的获取元素的方式,顺序看起来杂乱无章(通常只用关心某个元素是否是其成员,不关心顺序)。TreeSet将元素存储在红黑树数据结构中,按照结果的升序保存对象。LinkedHashSet因为查询速度也使用了hash,同时使用了链表来维护顺序,按照添加的顺序保存对象。

HashMap是最快的获取元素的方式,顺序看起来杂乱无章。TreeMap按照结果的升序保存对象。LinkedHashMap按照添加的顺序保存键,同时还保留了HashMap的查询速度。

List在Collection的基础上添加了较多的方法。ArrayList 和LinkedList两种,前者在随机访问方面有较大优势,在插入和移除的时候较慢。后者插入和删除的代价较低,顺序访问也较快,但是对于随机访问则相对较慢。

迭代器(也是一种设计模式):我们在设计的时候一直考虑的是,怎么去抽象到更高的高度,不对确切的内容进行编程,而是抽象到更高的高度,方便复用。接收对象容器并使用它,使每个对象都能执行操作。

class Pets{
    List<String> pets=new ArrayList<>();
    public List<String> getPets(){
        pets.add("pet1");
        pets.add("pet2");
        pets.add("pet3");
        return pets;
    }

}

public class IteratorTest {
    public static void display(Iterator<String> it){
        while (it.hasNext()){
            String s=it.next();
            System.out.print(s);
        }
        System.out.println();
    }
    public static void display(Collection<String> c){
        for (String s:c) {
            System.out.print(s);
        }
        System.out.println();
    }
    public static void main(String args[]){
        Pets p=new Pets();
        List<String> petsList=p.getPets();
        Set<String> petsSet=new HashSet<>(petsList);
        Map<String,String> petsMap=new HashMap<>();
        String[] name=("cat,pig,dog".split(","));
        for (int i=0;i<3;i++){
            petsMap.put(name[i],petsList.get(i));
        }
        display(petsList);
        display(petsSet);
        display(petsList.iterator());
        display(petsSet.iterator());
        System.out.println(petsMap);
        System.out.println(petsMap.keySet());
        display(petsMap.keySet());
        display(petsMap.values());
        display(petsMap.values().iterator());

    }
}

迭代器就是为了达到这样的目的。迭代器是一个对象,遍历并选择其中的对象。不用关心底层的结构。Java的interator只能单向移动。使用方法interator()要求容器返回一个Interator对象,其准备好返回序列的第一个元素,使用next返回下一个,hasnext检查是否还有下一个,remove将元素删除。在调用remove前一定要调用next。

ListInterator是更强大的interator的子类型。可以双向移动。

Linkedlist额外提供了栈,队列,双端队列的方法。

Stack栈,后进先出的容器LIFO,自助餐托盘。实际上LinkedList就能当栈来使用。

public class Stack<T> {
    //大概的了解栈的功能,了解本质上Linkedlist是可以实现栈的功能的
    private LinkedList<T> storage=new LinkedList<>();
    public void push(T t){storage.add(t);}
    public T peek(){return storage.getFirst();}
    public T pop(){return storage.removeFirst();}
    public boolean isEmpty(){return storage.isEmpty();}
    public String toString(){return  storage.toString();}
}

public class StackTest {
    public static void main(String args[]){
        java.util.Stack<String> stack=new Stack<>();
        for (String s:"my name is haha".split(" ")
             ) {
            stack.push(s);
        }
        while (!stack.isEmpty()){
            System.out.println(stack.pop());
        }
    }
}

Set不保存重复的元素,实际上set就是collection。

Map与其他的Collection一样,很容易就扩展为多维的形式。可多重嵌套使用。例如跟踪某个拥有多个宠物的人,Map<Person,List<Pet>>.Map可以返回它的key的Set,它的键值对的set。keyset()方法产生了前者的set集合,可以方便用foreach语法进行遍历。

public class MapTest {
    public static void test1(){
        Random random=new Random(47);
        Map<Integer,Integer> m=new HashMap<>();
        for(int i=0;i<1000;i++){
            int r= random.nextInt(20);
            Integer freq=m.get(r);
            m.put(r,freq==null?1:freq+1);//这种语法有点意思
        }
        System.out.println(m);
    }
    public static void test2(){
        Map<String,Animal> map=new HashMap<>();
        map.put("cat",new Animal("miao"));
        map.put("dog",new Animal("wang"));
        System.out.println(map);
        Animal dog=map.get("dog");
        System.out.println(dog);
        System.out.println(map.containsKey("cat"));
        System.out.println(map.containsValue(dog));
    }
    public static void main(String args[]){
        test1();
        test2();
    }
}


class Animal{
    String name;
    public Animal(String name){
        this.name=name;
    }
}

Queue队列,典型的先进先出FIFO,在并发编程中特别重要。实际上LinkedList就能当队列来使用。注意还存在PriorityQueue即是优先级队列。队列规则是给定一组队列中的元素的情况下,下一个弹出队列元素的规则。先进先出声明的是下一个元素应该是等待时间最长的元素。优先级队列返回的元素是最需要的元素,如飞机场某飞机要起飞,该飞机的乘客可以优先登机。当优先队列调用offer方法进行插入对象的时候,对象会自动根据规则排序。同时peek,poll,remove的时候也是获取的优先级最高的。注意可以通过自己提供Comparator方法来修改顺序。

public class QueueTest {
    public static void main(String args[]){
        Queue<Integer> queue=new LinkedList<>();
        //我注意到,如果是对于Stack而言,后面的实现我写出Stack<String> s=new Stack<>();是默认OK的
        //但是对于Queue,我写了相似的结构以后,马上出了一堆方法要我覆盖
        //offer方法将一个元素插入到队尾或者返回false
        //peek方法和element方法都在不移除的情况下返回队头
        //peek方法在队列为空的时候返回null,而element方法返回NoSuchElementException异常
        //poll和remove方法将移除并返回对头,但poll方法在队列为空的时候返回null,而remove抛出NoSuchElementException异常
        Random random=new Random(47);
        for (int i=1;i<10;i++){
            queue.offer(random.nextInt(i+10));
        }
        printQ(queue);
        System.out.println(queue);
        Queue<Character> qc=new LinkedList<>();
        for (char c:"Helloworld".toCharArray()){
            qc.offer(c);
        }
        System.out.println(qc);
        printQ(qc);
    }
    public static void printQ(Queue q){
        while (q.peek()!=null){
            System.out.println(q.remove());
        }
    }
}

foreach可以用于数组,也可以用于任何collection对象。之所以能够正常工作,是因为Javase5引入了新的Iterator接口,该接口包含一个能产生Iterator的iterator方法。如果你创建了Iterable实现的类,都可以用于foreach。

Java提供了大量关于持有对象的操作,数组将数字与对象关联起来。保存类型明确的对象,查询对象的时候无需类型转换。数组一旦形成就不能改变大小。

public class ForeachCollections {
    public static void main(String args[]){
        Collection<String> cs=new LinkedHashSet<>();
        Collections.addAll(cs,"go home or go big".split(" "));
        for (String s:cs
             ) {
            System.out.println(" "+s+" ");
        }
    }
}
只要实现了Iterable类就可以用于foreach中。
public class IterableClass implements Iterable<String> {
    //这段很精彩,要背背
    //返回了实现Iterator<String>的匿名内部类的实例
    protected String[] words=("you should study hard so you can go big".split(" "));
    public Iterator<String> iterator(){
        return new Iterator<String>() {
            private int index=0;
            public boolean hasNext() {
                return index<words.length;
            }
            public String next() {
                return words[index++];
            }
            public void remove(){
                throw new UnsupportedOperationException();
            }
        };
    }
    //注意这个地方的ItearbleClass
    public static void main(String args[]){
        for (String s:new IterableClass()
             ) {
            System.out.println(s);
        }
    }
}

Collection保存单一的元素,而map保存相关联的键值对。有了Java泛型就可以指定容器中存储对象的类型,并且取出元素时候无需进行类型转换。容器大小可自动调整,容器不能存放基本数据类型,但是包装机制可以实现双向转换。各种栈和队列的行为,由linkedlist提供支持。

map是一种将对象(而非数字)与对象相关联的设计。hashmap用于快速访问,treemap用于保持键始终是排序状态,linkedhashmap保持插入的顺序同时也提供快速访问的支持。

Set不接受相同的元素。hashset快速查询,treeset保持排序状态,linkedhashset保持插入顺序也提供快速访问机制。

下载前可以先看下教程 https://pan.quark.cn/s/a426667488ae 标题“仿淘宝jquery图片左右切换带数字”揭示了这是一个关于运用jQuery技术完成的图片轮播机制,其特色在于具备淘宝在线平台普遍存在的图片切换表现,并且在整个切换环节中会展示当前图片的序列号。 此类功能一般应用于电子商务平台的产品呈现环节,使用户可以便捷地查看多张商品的照片。 说明中的“NULL”表示未提供进一步的信息,但我们可以借助标题来揣摩若干核心的技术要点。 在构建此类功能时,开发者通常会借助以下技术手段:1. **jQuery库**:jQuery是一个应用广泛的JavaScript框架,它简化了HTML文档的遍历、事件管理、动画效果以及Ajax通信。 在此项目中,jQuery将负责处理用户的点击动作(实现左右切换),并且制造流畅的过渡效果。 2. **图片轮播扩展工具**:开发者或许会采用现成的jQuery扩展,例如Slick、Bootstrap Carousel或个性化的轮播函数,以达成图片切换的功能。 这些扩展能够辅助迅速构建功能完善的轮播模块。 3. **即时数字呈现**:展示当前图片的序列号,这需要通过JavaScript或jQuery来追踪并调整。 每当图片切换时,相应的数字也会同步更新。 4. **CSS美化**:为了达成淘宝图片切换的视觉效果,可能需要设计特定的CSS样式,涵盖图片的排列方式、过渡效果、点状指示器等。 CSS3的动画和过渡特性(如`transition`和`animation`)在此过程中扮演关键角色。 5. **事件监测**:运用jQuery的`.on()`方法来监测用户的操作,比如点击左右控制按钮或自动按时间间隔切换。 根据用户的交互,触发相应的函数来执行...
垃圾实例分割数据集 一、基础信息 • 数据集名称:垃圾实例分割数据集 • 图片数量: 训练集:7,000张图片 验证集:426张图片 测试集:644张图片 • 训练集:7,000张图片 • 验证集:426张图片 • 测试集:644张图片 • 分类类别: 垃圾(Sampah) • 垃圾(Sampah) • 标注格式:YOLO格式,包含实例分割的多边形点坐标,适用于实例分割任务。 • 数据格式:图片文件 二、适用场景 • 智能垃圾检测系统开发:数据集支持实例分割任务,帮助构建能够自动识别和分割图像中垃圾区域的AI模型,适用于智能清洁机器人、自动垃圾桶等应用。 • 环境监控与管理:集成到监控系统中,用于实时检测公共区域的垃圾堆积,辅助环境清洁和治理决策。 • 计算机视觉研究:支持实例分割算法的研究和优化,特别是在垃圾识别领域,促进AI在环保方面的创新。 • 教育与实践:可用于高校或培训机构的AI课程,作为实例分割技术的实践数据集,帮助学生理解计算机视觉应用。 三、数据集优势 • 精确的实例分割标注:每个垃圾实例都使用详细的多边形点进行标注,确保分割边界准确,提升模型训练效果。 • 数据多样性:包含多种垃圾物品实例,覆盖不同场景,增强模型的泛化能力和鲁棒性。 • 格式兼容性强:YOLO标注格式易于与主流深度学习框架集成,如YOLO系列、PyTorch等,方便研究人员和开发者使用。 • 实际应用价值:直接针对现实世界的垃圾管理需求,为自动化环保解决方案提供可靠数据支持,具有重要的社会意义。
### Java中的组合、聚合和关联关系 #### 组合(Composition) 组合是一种特殊类型的关联,其中整体与部分之间的生命周期紧密相连。当整体被销毁时,其所有的组成部分也会随之消失。这表明,在组合中,部分对象不能独立于整体对象而存在。 ```java class Engine { // engine details... } class Car { private final Engine engine; public Car() { this.engine = new Engine(); // 创建Car的同时创建Engine } } ``` 上述代码展示了`Car`类和`Engine`类间的组合关系[^1]。每当创建一个新的`Car`实例时,都会自动初始化一个对应的`Engine`实例;如果`Car`对象不再使用,则该特定的`Engine`也将无法访问并最终由垃圾回收器处理。 #### 聚合(Aggregation) 相比之下,聚合描述了一种较弱的整体-部分关系,允许部件可以在不同时间属于不同的整体或根本不隶属于任何整体。这意味着即使整体不存在了,组成它的各个部分仍然能够继续存活下去。 ```java import java.util.ArrayList; import java.util.List; class Department { String name; public void setName(String n){ this.name=n; } @Override public String toString(){ return "Department Name:"+name; } } class University { List<Department> departments = new ArrayList<>(); public void addDepartment(Department d) { departments.add(d); } } ``` 这里定义了一个大学(`University`)拥有多个院系(`Departments`)的例子[^4]。值得注意的是,即便某个具体的`University`实体消失了,那些曾经归属于它的`Department`们依然可能存在,并可能转移到其他院校之下。 #### 关联(Association) 关联是最基本的对象间连接形式之一,它可以简单到只是两个类之间相互持有对方的一个引用而已。这种联系既可以是单向也可以是双向的,具体取决于业务逻辑需求以及设计者的选择。 ```java class Teacher { Student student; // 构造函数或其他方法设置student属性... public void setStudent(Student s){ this.student=s; } } class Student { Teacher teacher; // 构造函数或其他方法设置teacher属性... public void setTeacher(Teacher t){ this.teacher=t; } } ``` 在这个例子中,教师(`Teacher`)和学生(`Student`)之间存在着一种典型的关联关系[^2]。两者互为对方提供服务——即教书育人过程中的指导作用。同时注意到,这段代码还暗示着二者之间的关系可能是双向可逆的,尽管实际应用里也完全可以是一方指向另一方的单向链接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值