Does Java have an equivalent variable type to C#'s Tuple?
Asked Answered
D

10

12

I am translating a program from C# to Java. In the C# code, the developer uses Tuple. I need to translate this C# code into Java code. Therefore, does Java have an equivalent variable type to C#'s Tuple?

Dodd answered 24/4, 2013 at 16:13 Comment(7)
Tuples are generally considered a bad idea in Java. It is better to use a custom class with named fields of specific types.Touraine
@PeterLawrey probably not the place to ask this but why would Tuples be a bad idea in Java when they're not in other languages? "considered a bad idea" sounds like a community preference that has no merit.Arrival
@AtishDipongkor yes, I believe there is a guideline like "don't ask to have language a translated to language b" however I didn't down vote, so idk.Arrival
@evanmcdonnal, there are lot of questions in this site like my question #1217728Dodd
@Arrival For the record, a lot of people thing they're a bad idea in other languages as well, such as in C#, or at the very least are frequently misused/abused when a new named type should be used.Burweed
100% agreed with @Servy, except in really specific situations, tuples are almost always a bad idea.Incogitant
@Arrival Java favours static typing and static invocation and it has relatively poor support for dynamic structures and execution. Other languages handle tuples more naturally, efficiently and consistently with it's other features. While you can have tuples in Java, if you are going to translate into Java I suggest you follow it's more static typing.Touraine
B
5

Due to type erasure, there is no way in Java to have exact mirrors of the various Tuple classes in .NET. However, here is a BSD-licensed implementation of Tuple2 and Tuple3 for Java, which mirror the Tuple<T1, T2> and Tuple<T1, T2, T3> types from .NET.

One cool thing you can do in Java but not C# is this:

class Bar extends Foo { }

...

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

In C#, you would have to use casts instead:

Tuple<Foo, Foo> tuple = Tuple.Create((Foo)new Bar(), (Foo)new Bar());
Buseck answered 24/4, 2013 at 16:39 Comment(4)
Your C# example isn't particularly good. The casts are superfluous.Burweed
@Burweed the point of the C# example is the casts are not superfluous.Buseck
Sorry, but no, the casts are not necessary in C#. The "Bar" class can be used as a "Foo", just like in Java or C++.Lupine
@Burweed and @Jamie, Tuple.Create(new Bar(), new Bar()) will return an instance of Tuple<Bar, Bar> - Tuple<Foo, Foo> tuple = Tuple.Create(new Bar(), new Bar()) will not compile, as Tuple doesn't support covariance. To make it work in c#, you'd need to use the constructor instead - Tuple<Foo, Foo> tuple = new Tuple<Foo, Foo>(new Bar(), new Bar())Eda
L
1

Probably a bit off topic, but have you considered Scala in a JVM environment? It has tuple support + a few other nice features that you might miss from C#.

Lederhosen answered 24/4, 2013 at 16:49 Comment(0)
L
1

There seems to be a pretty decent looking Tuple library at https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html. Three elements is the largest it can be, but if you need a Tuple larger than three, you should probably give up and define a class.

Lupine answered 11/4, 2017 at 23:52 Comment(0)
B
1

it's quite old topic, but i will leave this what i recently used during converting C# tuples(Tuple) in Java project - you can simply use org.javatuples lib - https://www.javatuples.org/, which will gives the same behavior to storing data.

Simple example below for people which will lookin for this later:

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

the same in 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
Berceuse answered 26/2, 2018 at 0:27 Comment(0)
S
1

I was in need of Tuple equivalent in my android project as well, but didn't found any native solution in Java. But surprisingly there is Pair.class in android's util which is exact what I was searching for.

So Android developers, who came across this question, use Pair.class in android.util package.

P.S. I'm sad to accept that there are a lot of things that Java is far behind from other languages already.

Swatter answered 14/1, 2020 at 13:32 Comment(0)
D
0

There might be implementations, but not in the JDK Library as far as I know. See here for an example of your own tuple: Using Pairs or 2-tuples in Java

Donniedonnish answered 24/4, 2013 at 16:14 Comment(0)
C
0

When you're using Spring Boot with WebFlux it comes with Project Reactor and that provides Tuples classes. The advantage of the Project Reactor implementation is they have a clean way of generating the Tuples using the .of operator

e.g.

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

I usually use it for date ranges as shown in this example to find the starting date of a range given a processing date.

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);

There's no need to memorize types like Pair, Triple, Decade, etc.

Charolettecharon answered 8/5, 2020 at 20:45 Comment(0)
O
0

This is a rather old question, but here is what I ended up developing to be able to use tuples in the post Java 8 world with all of its functional tools and the nicer fluent language: https://github.com/mmnaseri/tuples4j/

It is already available in Maven Central, too, so it is very easy to get a hold of.

Odel answered 12/5, 2020 at 6:48 Comment(0)
N
0

At least a 2-tupel exists in Java, right from the beginning: java.util.Map.Entry<K,V>! Ok, it is an interface only …

But since Java 9, there is the static method java.util.Map.entry() that allows the creation of instances of that interface on the fly (in fact, instances of a hidden class implementing that interface, but who cares about that little detail?).

I would not like to use that in the definition of a public API that is not dealing with Collections, but for an internal utility class … why not? The class already exists in the JRE, no additional external dependency, and I can live with the fact that the elements are named "key" and "value" instead of "item1", "item2", …

Nieves answered 12/5, 2020 at 7:9 Comment(0)
P
-1

I am not a C# developer but given the documentation I just looked at about Tuple in C# I can't imagine what you would/could/SHOULD use something like this.

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

Looking at this code I have no earthly clue what those values represent and can't imagine why you wouldn't use a class.

As I see it, this just represents poor encapsulation.

However, if you want a Tuple in Java, the only one I know of is

Map.Entry<K,V>

And it's really only appropriate for use in Maps

Pavkovic answered 24/4, 2013 at 16:58 Comment(1)
Maybe you should become a C# developer. Where you could use those values is when you need a quick array or something to populate a ComboBox. You could have one item represent the object itself, another for display value (DisplayMember) and another for SelectedValue (there are times when you want this different than SelectedItem). But wait, there anonymous types in C#. So for a simple CSV reader Tuple would've been perfect, if I know the type of each data column. Because Java sucks balls, I have to create a class for each scenario. The items borrowed from C# also suck balls in Java...Kristopherkristos

© 2022 - 2024 — McMap. All rights reserved.