【问题标题】:Converting an int array to a String array将 int 数组转换为 String 数组
【发布时间】:2011-04-06 21:34:03
【问题描述】:

所以我有这个整数“列表”。它可能是Vectorint[]List<Integer>,等等。

我的目标是对整数进行排序并最终得到String[]。 int 数组是如何开始的。

例如: 开头:{5,1,2,11,3} 结尾:String[] = {"1","2","3","5","11"}

在没有 for 循环的情况下有没有办法做到这一点?我现在有一个用于收集整数的 for 循环。我宁愿跳过做另一个 for 循环。

【问题讨论】:

  • 请用适当的语言重新标记您的问题。
  • 为什么要避免 for 循环?任何人提出的任何解决方案都会有某种循环,即使它隐藏在方法调用后面。
  • @Rudi 它可能在发布后 5 分钟内被编辑,在这种情况下,编辑不会显示。
  • 好像是两个操作。我该如何排序? [Arrays.sort/Collections.sort] 如何将in[]/List<Integer> 转换为String[]? [见stackoverflow.com/questions/18524/…]
  • 为了解决您对多个 for 循环的恐惧,我会寻求专业帮助。从阅读重构 (Martin Fowler) 和有效使用遗留代码 (Michael Feathers) 开始...

标签: java arrays list int


【解决方案1】:
int[] nums = {5,1,2,11,3}; //List or Vector
Arrays.sort(nums); //Collections.sort() for List,Vector
String a=Arrays.toString(nums); //toString the List or Vector
String ar[]=a.substring(1,a.length()-1).split(", ");
System.out.println(Arrays.toString(ar));

更新:

更短的版本:

int[] nums = {-5,1,2,11,3};
Arrays.sort(nums);
String[] a=Arrays.toString(nums).split("[\\[\\]]")[1].split(", "); 
System.out.println(Arrays.toString(a));  

【讨论】:

  • 我认为这可能是答案。我不想再次遍历列表,因为我已经在迭代以获取 int 列表。谢谢。
  • 如果您担心速度,那么最好再次使用普通的 for 循环,因为在 Arrays.toString() 中他们使用的是 for 循环。检查源(docjar.com/html/api/java/util/Arrays.java.html)但如果你只是想让你的代码看起来很小那么好吧,你可以使用上面的代码或其他选项只是编写小函数来发送一个 int[] 作为输入并返回 String[] 数组作为输出。
  • “[\[\]]”是一个正则表达式,对吧?你是怎么知道要使用哪一个的,它到底在指示什么?
  • 想法是使用Arrays.toString
【解决方案2】:

使用可从 Java 8 获得的 Stream。要获取带有整数“列表”的 Stream 实例:

  • int[]
    • IntStream intStream = Arrays.Stream(nums);
    • Stream<Integer> intStream = Arrays.Stream(nums).boxed(); 如果您需要与底部相同的课程。
  • 对于任何具有Collection<Integer> 接口的类(例如Vector<Integer>List<Integer>
    • Stream<Integer> intStream = nums.stream();

最后,得到String[]

String[] answer = intStream.sorted().mapToObj(String::valueOf).toArray(String[]::new);

【讨论】:

    【解决方案3】:

    我可以改用while 循环吗?

    @Test
    public void test() {
        int[] nums = {5,1,2,11,3};
    
        Arrays.sort(nums);
    
        String[] stringNums = new String[nums.length];
        int i = 0;
        while (i < nums.length) {
            stringNums[i] = String.valueOf(nums[i++]);
        }
    
        Assert.assertArrayEquals(new String[]{"1","2","3","5","11"}, stringNums);
    }
    

    使用 JUnit 断言。

    对不起,我太轻率了。但是说你不能使用for 循环是愚蠢的——你必须以某种方式迭代 列表。如果您要调用一个库方法来为您排序(参见Collections.sort()) - 这将在元素上以某种方式循环。

    【讨论】:

      【解决方案4】:

      使用Guava的简单解决方案:

      public List<String> toSortedStrings(List<Integer> ints) {
        Collections.sort(ints);
        return Lists.newArrayList(Iterables.transform(ints, 
            Functions.toStringFunction()));
      }
      

      显然,此解决方案(与其他任何解决方案一样)将在内部使用循环,但它会将其从您必须阅读的代码中提取出来。您还可以通过将Ordering.natural().sortedCopy(ints) 的结果传递给transform 而不是首先使用Collections.sort 来避免更改ints 中的顺序。此外,如果您不需要能够将新元素添加到结果列表中,则不需要 Lists.newArrayList 部分。

      该方法体的缩短版本,带有静态导入:

      return transform(Ordering.natural().sortedCopy(ints), toStringFunction());
      

      【讨论】:

        【解决方案5】:

        如果您使用 TreeSet,我会为您准备一个(较长的)单线(假设 items 是 TreeSet):

        final String[] arr =
            items.toString() // string representation
                .replaceAll("\\D+", " ") // replace all non digits with spaces
                .trim() // trim ends
                .split(" "); // split by spaces
        

        测试代码:

        Set<Integer> items = new TreeSet<Integer>(Arrays.asList(5, 1, 2, 11, 3));
        
        // insert above code here
        
        System.out.println(Arrays.toString(arr));
        

        输出:

        [1, 2, 3, 5, 11]
        

        编辑:

        好的,这是一个直接与 int 数组一起使用的不同版本。但不幸的是,它不是单行的。但是,它确实会保留重复项,而且可能更快

        再次编辑:

        已根据要求修复了错误并支持负数:

        再次编辑:只有一个正则表达式通过,没有修剪

            final int[] in = { 5, 1, 2, 11, 3, 2, -5 }; // with duplicate
            Arrays.sort(in);
            final String[] out =
                Arrays.toString(in)
                    .replaceAll("(?:\\[?)([-\\d]+)(?:\\]?)", "$1") // just remove [ and ]
                    .split("\\s*,\\s*"); // split by comma
        
            System.out.println(Arrays.toString(out));
        

        输出:

        [-5, 1, 2, 2, 3, 5, 11]
        

        或完全不使用正则表达式(除了 split()),但又增加了一步:

        final int[] in = { 5, 1, 2, 11, 3, 2, -5 }; // with duplicate
        Arrays.sort(in);
        final String stringRep = Arrays.toString(in);
        final String[] out =
            stringRep.substring(1, stringRep.length() - 1).split("\\s*,\\s*");
        
        System.out.println(Arrays.toString(out));
        

        输出:

        [-5, 1, 2, 2, 3, 5, 11]
        

        更新:从我的最后两个解决方案中删除了空格,希望你现在开心:-)

        【讨论】:

        • 这不适用于具有超过 1 个相同元素的任何数组或列表。
        • +1 @ColinD。 TreeSet 将为您排序数字,但它也会删除重复的数字,这不是预期的。
        • 我知道,但没人说过要骗人
        • 列表和数组(在问题中提到)保持重复,所以我觉得它有点含蓄。
        • 正确处理负数所需的少量更改,并且使用未定义的arr 代替in...
        【解决方案6】:

        我宁愿跳过做另一个 循环。

        这很愚蠢。这是进行代码练习的愚蠢愿望和愚蠢基础。如果你能更好地表达你希望你的代码具有的品质,那么我们就有话要说——它应该易于阅读,比如说,或者高性能,或者可测试,或者健壮。但是“我宁愿跳过它”并没有给我们任何有用的东西。

        【讨论】:

        • 因为我已经循环获取列表。感谢您的参与。
        【解决方案7】:

        使用Functional Java

        import fj.data.List;
        import static fj.data.List.*;
        import static fj.pre.Show.*;
        .
        .
        .
        final List<Integer> xs = list(5,1,2,11,3);
        final List<String> ys = xs.sort(Ord.intOrd).map(
          new F<Integer, String>() {
            @Override public String f(final Integer i) {
               return String.valueOf(i);
            }
          }
        );
        listShow(stringShow).println(ys);
        

        【讨论】:

        • 太酷了!! (如果我还有剩余的选票,我会投赞成票):-)
        • @seanzier:谢谢,非常感谢! :)
        【解决方案8】:

        这样的事情怎么样:

        List<String> stringList = new ArrayList<String>();
        List<Integer> list = new ArrayList<Integer>(Arrays.asList(5,1,2,11,3));
        Collections.sort(list);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()) {
          stringList.add(iterator.next().toString());
        }
        System.out.println(stringList);
        

        【讨论】:

          【解决方案9】:

          使用Eclipse CollectionsMutableIntList

          String[] result = IntLists.mutable.with(5, 1, 2, 11, 3)
                  .sortThis()
                  .collect(Integer::toString)
                  .toArray(new String[]{});
          
          Assert.assertArrayEquals(
                  new String[]{"1", "2", "3", "5", "11"}, result);
          

          或者用一些可读性换取潜在的效率:

          MutableIntList intList = IntLists.mutable.with(5, 1, 2, 11, 3).sortThis();
          String[] result = intList.injectIntoWithIndex(
                  new String[intList.size()], 
                  (r, each, index) -> {
                      r[index] = Integer.toString(each);
                      return r;
                  });
          
          Assert.assertArrayEquals(
                  new String[]{"1", "2", "3", "5", "11"}, result);
          

          注意:我是 Eclipse Collections 的提交者

          【讨论】:

            【解决方案10】:

            您可以使用Collections.sort(),然后遍历列表并收集String.valueOf() 每个元素。

            http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#sort%28java.util.List%29

            对于向量,您首先会得到一个带有Collections.list(Enumeration e) 的列表。

            对于数组,您可以使用Arrays.sort() 而不是Collections.sort()

            http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#sort%28int%5b%5d%29

            【讨论】:

            • 哦,是的。我不使用 Vector s,因为它们已经过时了,所以我不知道它们变成了 List s。我记得你什么时候用Vector.elements() 迭代它们(很久以前)。
            • Vector、Hashtable、StringBuffer:这些类都有些过时了,但人们仍在使用它们。新人也一样。我想知道他们从哪里学到的……
            • @seanizer:我从来没有听说过StringBuffer过时了。可以参考任何文章吗?
            • StringBuilder 在大多数情况下已过时 StringBufferdownload.oracle.com/javase/1.5.0/docs/api/java/lang/…
            【解决方案11】:

            为什么不简单地将这些值转换为原始 for 循环中的 String,创建一个 String 数组而不是 int 数组?假设您从起点收集初始整数并在每次 for 循环迭代中添加它,以下是创建 String 数组而不是 int 数组的简单方法。如果您需要其中具有相同值的 int 和 String 数组,请在同一个 for 循环中创建它们并完成它。

            yourInt = someNumber;
            
            for (int a = 0; a < aLimit; a ++) {
            
            String stringName = String.valueOf(yourInt);
            StringArrayName[a] = stringName;
            yourInt ++;
            
            }
            

            或者,如果您需要两者:

            yourInt = someNumber;
            
            for (int a = 0; a < aLimit; a ++) {
            
            String stringName = String.valueOf(yourInt);
            StringArrayName[a] = stringName;
            intArrayName[a] = yourInt;
            yourInt ++;
            
            }
            

            我同意其他所有人的观点。 for 循环易于构建,运行几乎不需要开销,并且在阅读代码时易于遵循。简约中的优雅!

            【讨论】:

            • 您的代码存在一些问题。 1.最重要的是,没有人在a++中使用空白,而它可能会起作用。不要试图在编码风格上保持个性! 2. yourInt, someNumber 是什么?它们在问题中不存在,您也没有声明或解释它们。 3. casting 在 Java 中是非常狭窄的定义术语。没有从 String 到 Int 的强制转换,因为 Int 不是 String 的子类。 4. 没有人使用s[a]=String.valueOf (yourInt);,但s[a] = "" + yourInt;。 5.为什么要对stringName进行中间赋值? 6.为什么违反编码风格,用StringArrayName[a]代替stringArrayName[a]?
            • 7.什么名字,stringArrayName!虽然它是一个整数数组作为名称。 8. 无缩进。所有这些问题都隐藏了您简单但优雅(如果适用)的想法。
            【解决方案12】:

            Java 8 方式,完全没有循环:

             // Given
            int[] array         = {-5, 8, 3, 10, 25};
            // When
            String[] actual = Arrays.stream(array)
                    .sorted()
                    .mapToObj(String::valueOf)
                    .toArray(String[]::new);
            // Then
            String[] expected = {"-5", "3", "8", "10", "25"};
            
            assertArrayEquals(expected, actual);
            

            【讨论】:

              【解决方案13】:

              我们可以使用正则表达式来解决这个问题:

              int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8};
              String str = new String(Arrays.toString(intArray));
              String stripNoneDigits= str.replaceAll("[^\\d]", "");
              String[] stringArray = stripNoneDigits.split("");
              

              【讨论】:

                【解决方案14】:

                Arrays.sort(nums); var stringArray = (nums.toString()).split(',').map(String);

                【讨论】:

                • 不要认为 Java 有 var 关键字。这看起来像 JavaScript
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-01-08
                • 1970-01-01
                • 2011-10-16
                • 2013-12-28
                • 2011-11-30
                • 1970-01-01
                相关资源
                最近更新 更多