【问题标题】:Java - Not Just Using ArrayList, but Creating It (Generics)Java - 不只是使用 ArrayList,而是创建它(泛型)
【发布时间】:2016-01-14 15:54:04
【问题描述】:

我知道在这样的网站上提出家庭作业通常不是一件好事。我不要求施舍,也不希望任何人为我完成任何事情。我一开始就这么说是因为你永远不知道,这里的某个人可能也有同样的任务。我不想被视为骗子或以任何方式依赖这个社区来完成我的家庭作业,就像一个被宠坏的孩子。我只是真诚地喜欢编程,我渴望更多地了解它。

我的目标只是了解泛型,以及如何使用它来使我的算法受益。我是数据结构课程的大二学生,教授希望我们创建一个程序来创建键值对。这些键值对是根据 Tom Sawyer 等书籍创建的单个对象。每个唯一词是一个键,然后值表示该唯一词在文本中出现的次数。他说每个键都是字符串,每个值都是整数。最终,我们将不得不分析这些书籍并将它们相互比较。我知道这需要一组 Pair 对象。创建 Pairs 很简单。

我明白这一点,我能够在不使用泛型的情况下成功创建和打印这些 Pair 对象。然而,项目变得更加复杂。我需要一个以上的数组,这些 Pairs 不会有一个整数作为 Value 而是一个 Double 以便我可以找到单词的频率,所以我意识到继续不使用泛型将导致更多的代码不必要。其他人在没有泛型的情况下这样做,但我的教授不断发表评论说“他们无缘无故地让他们的生活变得更加艰难”。在我之前的所有编程课程中,都有一个实验室来陪伴他们,而且我们在学习代码方面有亲身体验。在那些类中没有提到任何称为泛型的东西。

很自然,我想让我的生活更轻松。我想理解和使用这个我以前从未见过的叫做泛型的东西。

许多其他人在当前作业中遇到问题,我已将我的代码提交给导师和教授本人。我已经发送了电子邮件等。我确实尝试了我能想到的每一种途径。我已经阅读了诸如此类的 Oracle Doc

https://docs.oracle.com/javase/tutorial/java/generics/types.html

但是这里的示例远不足以对我的情况有所帮助,要么就是这个问题,要么就是在我的头上飞来飞去。

他甚至将作业的截止日期延长了一整周,因为他收到了很多关于如何执行此操作的电子邮件。

但无论我看到谁,或者他们建议什么,我总是盯着我的代码,只是拒绝编译。它给了我说“通用数组创建”的错误,但我不确定为什么我不能创建这个数组。我读过很多人建议不要使用数组,而是使用 ArrayList。但是问题是我的教授不希望我们使用 ArrayList。他希望我们基本上建立我们自己的。例如我命名我的arrayPair。

我创建了一个通用的 Pair 类。按照他的建议。我创建了通用 arrayPair 类。这个类真的是一个似乎拒绝编译的类。我有一个包含主要功能的 Driver 类,它使用带有分隔符的 Scanner 和 StringTokenizer 来检索所有单个单词。然后我将它们转换为小写。

我还有一个接口,我命名为 Dictionary

这里是词典界面:

public interface Dic<K,V>

{

    void set(K key, V value);
    void remove(K key); 
    void reset();
    boolean isFound(K key);
    void next();
    K getCurrentKey();
    V getCurrentValue();
    void changeValue(V value);
}

这样就可以编译了,一切都很好。

到目前为止,我知道泛型的作用以及它们为何有用(至少我认为)。它们允许您以多种不同的方式实现相同的代码。您可以稍后指定这些“类型”是什么,它们可以是字符串、整数或任何您想要的,甚至是对象。我的教授说泛型适用于整数、字符串和双精度数。但后来我在互联网上做了一些阅读,然后我看到了这个。

http://www.tutorialspoint.com/java/java_dictionary_class.htm

我注意到键和值是对象。不是字符串或整数。

然后我看到了这个:

Why don't Java Generics support primitive types?

等一下,Java 泛型不支持原始类型?那么我的教授在说什么?

本网站上提供的许多示例或解决方案也使用 ArrayList,然后我很失望,因为这正是我被告知不要使用的。

所以也许我错过了一些非常简单的东西,只是这个概念让我发疯。

我想我所能做的就是向你们提供好人,我的 arrayPair 类。

我已经多次改变了我编写第 22 行和第 40 行语法的方式,这太疯狂了。我盯着这个东西看了好几个小时。请注意,其中一些字段只是在那里,因为我在一段时间内一直在纠结不同的想法。有些只是无用的字段。错误显示在第 11 行和第 21 行(不包括白线)。

public class arrayPair<K, V> implements Dictionary<K, V>
{

    private int capacity = 100; //Default capacity for pair array.

    private int card = 0;

    private Pair reference; //Used to store referenceerence to an array slot.

    private int iterator = 0; //Used to iterate through the array.

    private String currentKey;

    private double currentValue;

    private boolean contains;

    private boolean stop;

    arrayPair[] pairs = new Pair<K,V>[capacity];

    private K key;

    private V value;

    private String temp;

    @SuppressWarnings("Unchecked") // I added this because I saw it around online, no idea if it is needed. Or what it dooes. 

    @Override 
    public void set(K key, V value)
    {
        K k = key;
        V v = value;

        Pair<K, V> pa = new Pair<K, V>();
        reference =pa;

        if(card == (capacity)-1)
        {
            doubleSize();
        }    
        if(!this.isFound(key)){

            pairs[card] = pa;
            card++;
            reset();
        }
        else{
            reference.increaseValue();
            reset();
        }
    }

非常感谢任何帮助或见解。只需将我推向正确的方向,我到底应该如何使用泛型来解决这个问题?它甚至看起来像什么?然后我在这个网站上看到,你把东西投射到一个物体上,我以前的课上从来没有被告知过。所以我不知道所需的语法,也不知道在我的情况下是否有必要。我也看不到当没有类来表示对象时它如何创建对象。这学期我刚刚变得非常困惑,但上学期我把它粉碎了。我认为这篇文章已经很长了,所以我不想添加我的其他课程。如果您也需要查看 Pair 课程,我可以提供。但它的写法和我被告知的完全一样。它也可以编译,但是将 Value 的值增加 1 是不可能的。它说“二元运算符 + 1 不能应用于类型 V”。

因此,泛型和基元的使用正在发生一些事情。我只是不明白什么。地狱,我不知道该相信什么了!

编辑:

这是所要求的 Pair 类。

    public class Pair<K, V>
{

public K key;

public V value;

public Pair(K k, V v)
{
    this.key=k;
    this.value=v;
}

public K getKey()
{
    return this.key;
}

public V getValue()
{
    return this.value;
}

public void setValue(V v)
{
     this.value = v + 1;
}

public String toString()
{
    String statement = ("Key: " + this.key + " " +"Value: " + this.value);

    return statement;
}

}

【问题讨论】:

  • 我建议你退出这门课程。你的教练可能已经脑死亡,癌症可能会感染你自己的大脑。
  • 欢迎来到 Stack Overflow,@EdwardJenkins!我只是想说这是一篇真的很长的帖子,我觉得你可以把它缩短一点以便更容易理解(你不必解释整个 i> 计划和目标。只是说你只是在寻找泛型的例子)......
  • 恭喜,你刚刚完成了学期论文 :-)
  • 哦,伙计...我不太确定如何回应。这是一个可怕的人。 D:就像我花了数千美元在这所大学开始这个学期一样。我也真的很抱歉它这么长,我只是想让它清楚我的代码应该做什么。显然我的代码根本不清楚......哦,这只是一个烂人。
  • @jlam55555 我的意思是......我不想失去理智或任何东西。只是想节省几百块钱,而不是退出课程。老实说,我一直害怕在这个网站上提问,我以为人们会告诉我这很容易。或者我只是不擅长编程。归根结底,我总是可以退学,下学期和另一位教授一起学习这门课。但我想也许 StackOverflow 包含可以帮助我避免退出的人。或许我可以回去向这位教授展示我的本事?

标签: java generics arraylist


【解决方案1】:

对你来说不是一个完整的答案,但我意识到你问了 15 个不同的问题,所以我会试着让你的大脑清醒一点。

我的教授说泛型可以处理整数、字符串和 也加倍。

没错。例如List&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;()List&lt;Double&gt; list = new ArrayList&lt;Double&gt;() 是有效的。 IntegerDouble 是原语 int 和 double 的对象包装类型。泛型只能与Objects 一起使用,因为它会变成类型转换。

但后来我在网上做了一些阅读,然后我看到了这个我 请注意,键和值是对象。不是字符串或 整数..

StringIntegerObjectObject 是 Java 的神,每个类型都派生自 Object

然后我看到了:为什么 Java 泛型不支持原始类型?所以 等一下,Java 泛型不支持原始类型?所以呢 我的教授在说什么?

正确。尝试将其放入 Java 中,List&lt;int&gt; list = new ArrayList&lt;int&gt;()。你会得到一个编译错误。为什么?因为泛型只适用于对象,而不适用于原语。对于int,你使用Integer,对于double,你使用Double,对于char,你使用Character,等等

为了尝试为您指明正确的方向,您的课程 arrayPair&lt;K,V&gt; 在运行时需要两种类型,K 和 V。在您的作业上下文中,K 将是 String,V 将是 Double . K 是 Tom Sawyer 文本中的唯一单词,V 是计算单词出现次数的Double

我将尝试向您展示泛型的用处。假设您将arrayPair 实例化为arrayPair&lt;String,Double&gt; test = new arrayPair&lt;String,Double&gt;()。假设有一个名为foo(K var, V var2) 的方法。实例化 arrayPair 后,foo 期望 var 为 String,var2 为 Double。如果您尝试调用foo(5,5),您的程序将无法工作,因为它需要一个String 和Double,但您给了它2 个整数。这有意义吗?

最后一个提示,你必须用对象声明泛型,但如果它是正确的包装类,你可以用原语进行操作。我的意思是,你创建了一个包含整数的列表,所以List&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;(),现在你可以在这个列表中添加一个int。 list.add(5)。这是 Java 的自动装箱/拆箱功能。

【讨论】:

  • 我很想使用 ArrayList。我被明确告知不要。当我创建这些通用对象时。我尝试使用 而不是 我仍然遇到错误。
【解决方案2】:

关于对象/原语,您的课程似乎基于 Java 1.4,但您使用的是更高版本?如果是这样,请参阅auto-boxing/unboxing

您需要的数据结构不是array,而是map

您似乎对java.util.Dictionary 有一个提示,所以看看Hashtable 的实现,更好的是Map


注意:

@SuppressWarnings("Unchecked") // 我添加这个是因为我看到它 在线,不知道是否需要。或者它的作用。

不符合:

我只是真诚地热爱编程,我渴望了解更多 关于它。

尤其是 goole/SO:What is SuppressWarnings ("unchecked") in Java?

【讨论】:

  • “你需要的数据结构不是数组而是映射”有人告诉我使用数组。对不起,我忘了谷歌未经检查的警告,我在谷歌搜索泛型。平均数。
【解决方案3】:

我刚刚发现这个link 说,

你不能有泛型类的数组。 Java 根本不支持它。

您应该考虑使用集合而不是数组。例如,

public static ArrayList&lt;List&lt;MyObject&gt;&gt; a = new ArrayList&lt;List&lt;MyObject&gt;();

另一个“解决方法”是创建一个像这样的辅助类class MyObjectArrayList extends ArrayList&lt;MyObject&gt; { } 然后创建一个MyObjectArrayList 的数组。

由于你的导师不允许你使用ArrayList,我想你会发现这更难。

您可以使用非泛型 Pair(例如 arrayPair[] pairs = new Pair[capacity];),但这会破坏您使用泛型的初衷。

如果您被允许在 Java 中使用 HashMap 或其他迭代类型,我猜,请改用它们。这是我最好的建议。

我希望这会有所帮助。

【讨论】:

  • 我在尝试使用泛型之前的版本。完全按照您的建议:arrayPair[] pairs = new Pair[capacity];我让它工作了,但那时还有很多编码工作要做。他说使用泛型是要走的路,它会为我节省很多精力。我的意思是这个人有博士学位,所以我假设他知道他在说什么……他只是说了这句话,没有提供一个实际的例子。
猜你喜欢
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 2022-08-09
  • 1970-01-01
相关资源
最近更新 更多