软件构造体会(二)复习笔记之再谈泛型

软件构造体会(二)复习笔记之再谈泛型

关于泛型,在本门课的课堂上以及实验中都有涉及到,我今天的心得主要从相关应用以及个人理解上来探讨泛型的问题。

首先定义:泛型:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型。
对于其应用,主要由以下两个特点:
1.把类型当作是参数一样传递
2.<数据类型>只能是引用类型

当然只了解定义对于完成操作时没有什么意义的,所以我们接下来结合以下操作来完成对泛型的解释与应用。简单的用自己的话概括就是在程序使用实现时用一个符号来代替所有的泛型,而后在需要调用的地方将泛型对应的类更改为实际的类或进行一些替换,便可完成泛型定义的各种操作,听起来还是比较方便的。

首先应用场景:对于泛型的应用场景,我主要归纳为以下四个类,将四个类型搞懂绝大多数的应用应该都没有问题了。

1.泛型表示接口

​ 这个内容在实验二中我们都已经有了很深的了解,而且泛型表示接口也是泛型的一个主要应用之一。通俗的来说,接口相当于对外的一种约定或者说标准,规定程序应该怎么完成,所以泛型与之结合一定要通过重写来完成,如实验中的代码:

public interface Graph<L> {
    
    /**
     * Create an empty graph.
     * 
     * @param <L> type of vertex labels in the graph, must be immutable
     * @return a new empty weighted directed graph
     */
    public static <L> Graph<L> empty() {
        return new ConcreteEdgesGraph<L>();
    }

    public boolean add(L vertex);
    }

由于接口对应的类也是与之对应的,所以便有了一种用法,用泛型表示类。(篇幅有限,所以只列了一部分)

2.泛型表示类

​ 在我们的使用中,泛型类最常用的用法为容器类,泛型类在类上定义泛型类型,并在用户使用该类时指定该类型,同时定义在类上的泛型也可以在类的方法中使用,关于泛型表示方法会在一会论述。

接下来我们看一些实例,如实验二中的代码:

public class ConcreteEdgesGraph<L> implements Graph<L> {
 public int set(L source, L target, int weight) {
        int result = 0;
        if (source == null || target == null || target == source || weight < 0) {//数据错误
            System.out.println("Data input error");
            result=-1;
        } else {
            if (!vertices.contains(source)) {//如果点没在集合中正常添加
                vertices.add(source);
            }
            if (!vertices.contains(target)) {
                vertices.add(target);
            }
            if (weight == 0) {
                Iterator<Edge<L>> edge_rem = edges.iterator();
                while (edge_rem.hasNext()) {//先将顶点移除c
                    Edge<L> next = edge_rem.next();
                    if (next.getTarget().equals(target) && next.getSource().equals(source)) {
                        result = next.getWeight();
                        edge_rem.remove();
                    }
                }
            } else {//若顶点权值大于0则将其移除
                Iterator<Edge<L>> edge_rem = edges.iterator();
                while (edge_rem.hasNext()) {
                    Edge<L> next = edge_rem.next();
                    if (next.getTarget().equals(target) && next.getSource().equals(source)) {
                        result = next.getWeight();
                        edge_rem.remove();
                    }
                }
                Edge<L> new_edge = new Edge<>(source, target, weight);
                edges.add(new_edge);
            }
            return result;
        }
        return result;
    }
}

3.泛型表示方法

有了前面的基础了解这个也比较简单了。方法上需要泛型,方法外部只关心该方法,而不关心类的其他部分,也就是只需要保证函数的输入数量一定即可,不需要对函数的类型进行太多的限定。

如实验二中的代码实例如下:

public Map<L, Integer> targets(L source) {
        Map<L, Integer> target_temp = new HashMap<>();//同上
        for (Edge<L> edge : edges) {
            if (source.equals(edge.getSource())) {
                target_temp.put((L) edge.getTarget(), edge.getWeight());
            }
        }
        checkRep();
        return target_temp;
    }

4.泛型通配符

泛型通配符在学习之前我也树不太了解的,但是看了一些示例代码用完自己的话来总结就是在内部需要对类型进行具体定义时,可以选择直接设置为泛型,这样能够避免许多的错误,同时也减少了工作量。由于实验中的代码没用相关的内容,所以我便直接选择了一些其他的例子来介绍这个功能。

public static void generic(List<?> data) {
	System.out.println("Test" + data.a(1));
}

泛型优点:
1.可以避免装箱和拆箱操作。

2.泛型的使用使我们的代码应用更广泛,减少了其他类型在定义了一个类型后无法使用代码情况的出现。

3.泛型允许定义类型安全的数据结构,而不必使用实际的数据类型。这可以显著提高性能并产生更高质量的代码,因为您可以重用数据处理算法,而无需复制特定类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值