【问题标题】:How to make a Java array behave like a JavaScript array?如何使 Java 数组表现得像 JavaScript 数组?
【发布时间】:2014-07-16 07:27:59
【问题描述】:

在 JavaScript 中,我可以编写如下代码:

var a = new Array();
a[2] = 'a';
a[20] = 'b';

这在 Java 上不起作用,关键是我不想指定它的确切长度。

写java的时候如何保持这种快乐的风格?

【问题讨论】:

  • 我可能是错的,但您使用数组的方式似乎表明您实际上想要一张地图——也就是说,当您输入时,您似乎想要获得'a' 2,输入20时得到'b'
  • 在 JavaScript 中,你有一个数组——它做了很多事情。在 Java 中,您可以(并且应该)在普通数组、Set、List 和 Map 之间进行选择,仅举几个主要的集合。有用于特定操作的专用容器。所有这些选择都允许您编写比 JavaScript 的“一刀切”方法更快、更高效的应用程序。
  • 您还对答案感兴趣吗?或者您想给我们更准确的信息?
  • 谢谢大家,这对我来说有点疯狂,因为我花了很多时间在 JavaScript 上。

标签: java


【解决方案1】:

如果您不想指定长度,可以这样使用 List:

List<Character> list = new ArrayList<>();
list.add('a');
list.add('b');

【讨论】:

    【解决方案2】:

    你不能。 Java 之于 Javascript 就像 ham 之于仓鼠一样。没有理由相信它们具有相同的语法。

    如果你想要一个稀疏数组,使用Map:

    final Map<Integer, Character> a = new LinkedHashMap<>();
    a.put(2, 'a');
    a.put(20, 'b');
    

    【讨论】:

    • 我不认为 Map 是用作数组的更好结构。它还有其他用途……
    • @Dani 对不起什么? Map 是一个出色的稀疏数组,因为 is 用于此目的。毕竟,除了 Map 的特殊情况之外,数组是什么?
    • 这只是一个意见。当然你可以用一个 Map 作为一个数组,我认为 Map 是一种数据结构,用来存储与某个键相关的值,而键通常还有另一个含义,只是列表中的一个位置。这是主观的东西,对不起
    • @Dani 那么这是一个错误的观点。我不明白你从哪里来。为什么使用带有50 空格的数组来存储两个值比使用专门为该任务设计的Map 更好?
    • 通常,如果您使用数组,您将使用它的所有位置,它可以增长和减少,但您不会留下空的位置。如果你要留下很多空的位置当然是map更好,但是在这种情况下首先想到一个数组是很奇怪的,map的key可能除了简单的索引之外还有另一个含义。如果您使用和数组是因为索引很重要,只是将一个元素放在另一个元素的左侧或右侧,这只是一个排序问题。如果键具有其他含义,则键可能不会具有连续值
    【解决方案3】:

    当你想要一个字符数组时,你可以这样做:

    char[] array = new char[30];
    array[2] = 'a';
    array[20] = 'b';
    

    【讨论】:

    • 谢谢,不想具体长度怎么办?
    【解决方案4】:

    JavaJavaScript 是两种不同的语言。你不能在两者中做同样的事情

    Java你可以写

    char[] arr=new char[2];
    arr[0]='a';
    arr[1]='b';
    

    如果不想指定长度,可以在Java中使用List

    List<Character> list=new ArrayList<>();
    list.add('a');
    list.add('b');
    

    【讨论】:

    • 我可以不用为它定义长度吗?
    • @igonejack 你可以在Java中使用List
    • "You have to..."ammm...可能是"you can...",他也可以实现其他集合..!!!
    【解决方案5】:

    正如其他人已经指出的那样:Java 和 JavaScript 是两个不同的东西。对于可变大小的容器,有Java collections framework

    但是要选择哪一个呢?这取决于你需要什么。从你的问题我可以想象两种情况:

    可变大小的索引容器:

    基本上是一个类似数组的列表。在 Java 中,除了其他列表实现之外,ArrayList 使用如下:

    List<Character> myList = new ArrayList<Character>(); 
    
    // insert element at the end of the list
    myList.add('a');
    
    // insert element at specific position in list
    myList.add(1, 'b');
    
    // this will fail, because there's no element at position 2!!!
    myList.add(3, 'c')
    

    从整数到字符的映射容器:

    在java中有很多map的实现,我推荐HashMap,这样使用:

    Map<Integer,Character> myMap = new HashMap<Integer,Character>(); 
    
    // insert mappings int -> char
    myMap.put(0, 'a');
    myMap.put(1, 'b');
    myMap.put(20, 'c');
    

    每个容器都有不同的用途。我建议阅读Java collections tutorial 以便能够选择最合适的一个。还要看看 tucuxi 的回答,因为他提出了一个模拟所需行为的解决方案,但考虑到(正如他自己所说)这不是 java 的做事方式!

    【讨论】:

      【解决方案6】:

      您始终可以自己编写。你不会得到语法,但大部分风味仍然存在。

      请注意,就效率而言,这是一个糟糕的主意。通过学习“Java 方式”做事,您可以编写很多 更好的代码。所有语言都是如此:违背语言的本质进行编程肯定会让您感到痛苦。

      但这里是代码:

      class MyArray<T> extends ArrayList<T> {
          public MyArray<T>() { super(); }
          public void add(int i, T value) { 
              if (size() < i) { 
                  ensureCapacity(i+1); // grow at most once instead of multiple times 
                  while (size() < i)) { 
                      add(null); // extend with a null object
                  }
                  add(value);
              } else {
                  add(i, value);
              }
          }            
      }
      

      现在您可以将普通的ArrayListMyArray 的实例进行比较:

      ArrayList<Character> a = new ArrayList<>();
      MyArray<Character> b = new MyArray<>()
      a.add(10, 'X'); // IndexOutOfBoundsException, size is 0
      b.add(10, 'X'); // no exception - you get [10 x null, 'X']
      b.get(10);      // returns 'X'
      

      请记住,JavaScript 数组可以被任意对象索引,而不仅仅是整数——而且 JavaScript VM 会尽可能尝试使用数字索引数组。对于任意索引,您需要使用 Java HashMap

      class MyArray2<T> extends HashMap<Object, T> {
          public MyArray2<T>() { super(); }
          public void add(Object o, T value) { set(o, value); }
      }
      

      然后您将用作:

      MyArray2<Character> c = new MyArray2<>()
      c.add("anything", '?');
      c.get("anything"); // returns '?'
      

      【讨论】:

      • 这太残酷了。在我看来,操作需要一种不同类型的容器,而不是不合适的容器的混乱变体(无意冒犯!)。 size() 那么在你的版本中有什么意义呢?我没有反对,但我不喜欢这种方法......
      • 这有点讽刺 - 但它 OP 要求的。自动增长的数组在 Java 中可能的,而上面的实现是为什么我们大多避免使用它们。我现在很想知道 Rhino(Java 中的 JS)是如何实现它们的……
      • 你的第二个例子是完全错误的!如果您将IntegerString 添加到TreeMap,那么它将爆炸 - 没有IntegerString 的自然排序,除非您定义Comparator&lt;Object&gt; 并将其传递给@ 987654334@在施工。
      • @BoristheSpider - 完全正确;将 TreeMap 替换为 HashMap
      • HashMap 的问题是它没有 any 顺序 - 循环值会产生随机顺序。 LinkedHashMap 保留插入顺序,这可能就足够了。
      【解决方案7】:

      这取决于,如果你要使用一个固定大小的数组,你可以使用:

      char myarray[]=new char[50];
      myarray[2]='a';
      myarray[20]='b';
      

      如果您要动态更改数组的大小,您可以使用像 ArrayList 之类的集合(查看文档)并在您想要的位置插入字符

      【讨论】:

        【解决方案8】:

        喜欢这个

        char arr[]=new char[30]; //declares an array which can hold 30 characters
            arr[2]='a';
            arr[20]='b';
        

        但是如果你不想指定长度,那么 arraylist 可以帮助你完成任务,因为数组的大小在 Java 中总是固定的

        【讨论】:

        • 哦,谢谢,但我的意思是我不想在定义数组时指定长度。
        • 你不能...数组的大小在 Java 中总是固定的。通常,您不使用数组,而是在此处使用 List 的实现 - 通常是 ArrayList,但还有许多其他可用的替代方案。当然,您可以从列表中创建一个数组作为最后一步 - 或者只是更改方法的签名以返回 List 开始。
        猜你喜欢
        • 2021-02-19
        • 1970-01-01
        • 1970-01-01
        • 2010-09-09
        • 2011-11-27
        • 2010-09-14
        • 2010-10-05
        • 1970-01-01
        • 2019-01-03
        相关资源
        最近更新 更多