【问题标题】:Does Java have an equivalent variable type to C#'s Tuple?Java 是否具有与 C# 元组等效的变量类型?
【发布时间】:2013-04-24 16:13:12
【问题描述】:

我正在将一个程序从 C# 翻译成 Java。在 C# 代码中,开发人员使用元组。我需要将此 C# 代码翻译成 Java 代码。那么,Java 是否有与 C# 的 Tuple 等价的变量类型?

【问题讨论】:

  • 元组在 Java 中通常被认为是一个坏主意。最好使用具有特定类型的命名字段的自定义类。
  • @PeterLawrey 可能不是问这个问题的地方,但为什么元组在 Java 中不是一个坏主意,而不是其他语言? “被认为是个坏主意”听起来像是一种没有价值的社区偏好。
  • @evanmcdonnal 作为记录,很多人认为他们在其他语言中也是一个坏主意,例如在 C# 中,或者至少在新命名时经常被滥用/滥用应该使用类型。
  • 100% 同意@Servy,除非在非常特殊的情况下,元组几乎总是一个坏主意。
  • @evanmcdonnal Java 偏爱静态类型和静态调用,它对动态结构和执行的支持相对较差。其他语言更自然、更有效地处理元组,并与它的其他特性保持一致。虽然您可以在 Java 中使用元组,但如果您要翻译成 Java,我建议您遵循它的更多静态类型。

标签: java c# .net tuples


【解决方案1】:

由于类型擦除,Java 中没有办法在 .NET 中拥有各种Tuple 类的精确镜像。但是,这是一个 BSD 许可的 Tuple2Tuple3 的 Java 实现,它反映了 .NET 中的 Tuple<T1, T2>Tuple<T1, T2, T3> 类型。

您可以在 Java 中而不是 C# 中做的一件很酷的事情是:

class Bar extends Foo { }

...

Tuple2<? extends Foo, ? extends Foo> tuple = Tuple.create(new Bar(), new Bar());

在 C# 中,您必须改用强制类型转换:

Tuple<Foo, Foo> tuple = Tuple.Create((Foo)new Bar(), (Foo)new Bar());

【讨论】:

  • 您的 C# 示例不是特别好。演员表是多余的。
  • @Servy C# 示例的重点是演员表不是多余的。
  • 抱歉,C# 中不需要强制转换。 “Bar”类可以用作“Foo”,就像在 Java 或 C++ 中一样。
  • @Servy 和 @Jamie, Tuple.Create(new Bar(), new Bar()) 将返回 Tuple&lt;Bar, Bar&gt; 的实例 - Tuple&lt;Foo, Foo&gt; tuple = Tuple.Create(new Bar(), new Bar()) 不会编译,因为元组不支持协方差。要使其在 c# 中工作,您需要改用构造函数 - Tuple&lt;Foo, Foo&gt; tuple = new Tuple&lt;Foo, Foo&gt;(new Bar(), new Bar())
【解决方案2】:

可能有点跑题了,但是您是否考虑过在 JVM 环境中使用 Scala?它具有元组支持 + 一些您可能会从 C# 中错过的其他不错的功能。

【讨论】:

    【解决方案3】:

    https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html 似乎有一个相当不错的元组库。三个元素是最大的,但如果你需要一个大于三个的元组,你可能应该放弃并定义一个类。

    【讨论】:

      【解决方案4】:

      这是一个相当老的话题,但我将保留我最近在 Java 项目中转换 C# 元组(Tuple)时使用的内容 - 你可以简单地使用 org.javatuples 库 - https://www.javatuples.org/,这将为存储数据提供相同的行为.

      下面的简单示例供稍后查找此内容的人使用:

      C#

      var tupleCs = new Tuple<string, string, string>("value1","value2","value3");
      Console.Writeline(tupleCs.Item1); => value1
      Console.Writeline(tupleCs.Item2); => value2
      Console.Writeline(tupleCs.Item3); => value3
      

      Java 中也是这样

      Triplet tupleJava = new Triplet("value1","value2","value3");
      System.out.println(tupleJava.getValue0()); => value1 
      System.out.println(tupleJava.getValue1()); => value2
      System.out.println(tupleJava.getValue2()); => value3
      

      【讨论】:

        【解决方案5】:

        我的 android 项目中也需要 Tuple 等价物,但在 Java 中没有找到任何本机解决方案。但令人惊讶的是,android 的实用程序中有Pair.class,这正是我正在寻找的。

        所以 Android 开发人员 遇到了这个问题,在 android.util 包中使用 Pair.class

        附: 我很难过接受 Java 在很多方面已经远远落后于其他语言。

        【讨论】:

          【解决方案6】:

          据我所知,可能有实现,但不在 JDK 库中。有关您自己的元组的示例,请参见此处:Using Pairs or 2-tuples in Java

          【讨论】:

            【解决方案7】:

            当您使用带有 WebFlux 的 Spring Boot 时,它带有 Project Reactor 并提供 Tuples 类。 Project Reactor 实现的优点是他们有一种使用.of 运算符生成元组的简洁方式

            例如

            Tuples.of("A", 1, myObject);
            

            我通常将它用于此示例中所示的日期范围,以查找给定处理日期的范围的开始日期。

            return schedules.stream()
               .map(s -> Tuples.of(s.getStartDate(), s.getStopDate().orElse(LocalDate.MAX)))
               .filter(range -> (!processingDate.isBefore(range.getT1())) && 
                                  processingDate.isBefore(range.getT2()))
               .findAny()
               .map(Tuple2::getT1);
            

            无需记住 Pair、Triple、Decade 等类型。

            【讨论】:

              【解决方案8】:

              这是一个相当老的问题,但这是我最终开发出来的,以便能够在后 Java 8 世界中使用元组及其所有功能工具和更流畅的语言:https://github.com/mmnaseri/tuples4j/

              它也已经在 Maven Central 中可用,因此很容易掌握。

              【讨论】:

                【解决方案9】:

                Java 中至少存在一个 2-tupel,从一开始就是:java.util.Map.Entry&lt;K,V&gt;!好吧,它只是一个界面……

                但是从 Java 9 开始,有一个静态方法 java.util.Map.entry() 允许动态创建该接口的实例(事实上,实现该接口的隐藏类的实例,但谁在乎这个小细节呢?) .

                我不想在不处理集合的公共 API 的定义中使用它,而是在内部实用程序类中使用它……为什么不呢?该类已经存在于 JRE 中,没有额外的外部依赖,而且我可以接受这样一个事实,即元素被命名为“key”和“value”而不是“item1”、“item2”……

                【讨论】:

                  【解决方案10】:

                  我不是 C# 开发人员,但鉴于我刚刚查看的有关 C# 中 Tuple 的文档,我无法想象你会/可以/应该使用这样的东西。

                  var population = new Tuple<string, int, int, int, int, int, int>(
                                             "New York", 7891957, 7781984, 
                                             7894862, 7071639, 7322564, 8008278);
                  

                  查看这段代码,我不知道这些值代表什么,也无法想象您为什么不使用类。

                  在我看来,这只是表示封装不佳。

                  但是,如果你想要一个 Java 元组,我知道的唯一一个是

                  Map.Entry<K,V>
                  

                  而且它真的只适合在地图中使用

                  【讨论】:

                  • 也许你应该成为一名 C# 开发人员。当您需要一个快速数组或其他东西来填充ComboBox 时,您可以使用这些值。您可以让一个项目代表对象本身,另一个代表显示值 (DisplayMember),另一个代表 SelectedValue(有时您希望这与 SelectedItem 不同)。但是等等,C# 中有匿名类型。因此,如果我知道每个数据列的类型,那么对于一个简单的 CSV 阅读器Tuple 将是完美的。因为 Java 很烂,所以我必须为每个场景创建一个类。从 C# 借来的东西在 Java 中也很烂……
                  猜你喜欢
                  • 2013-07-25
                  • 2011-06-13
                  • 2010-12-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-11-20
                  • 2012-01-15
                  相关资源
                  最近更新 更多