Java的钥匙值对有序集合

发布于 2025-02-07 11:00:21 字数 899 浏览 2 评论 0 原文

我有一个带有列的2D表: Language 熟练度,我需要用输入来填充。

我已经创建了一个方法:

public void typeLanguages(@NotNull List<String> languages,
                          @NotNull List<SkillLevel> skillLevels) {

    if(languages.size() != skillLevels.size()) { throw new IllegalArgumentException(); }

    IntStream.range(0, skillLevels.size()).forEach(i -> {
        typeAndConfirm(languagesFld.get(i), languages.get(i));
        typeAndConfirm(skillFld.get(i), skillLevels.get(i).getLangSkill());
    });
}

intstream 已被使用,因此 i -th language-skilllevel 对插入 i -th Row。

SkillLevel 是一个枚举,它实现 getlangskill()方法,返回的方法是字符串的四个熟练度级别之一

,但是,用户可以提供不同尺寸列表的风险( 虽然受保护),或者他们可以混合订单并给自己错误的熟练程度得分。

afaik在爪哇没有任何元素。我尝试使用MAP,但看不到任何可以让我使用 i 的方法 - 地图的元素。

I have a 2D table with columns: Language and Proficiency, which I need to populate with the input.

I've created a method:

public void typeLanguages(@NotNull List<String> languages,
                          @NotNull List<SkillLevel> skillLevels) {

    if(languages.size() != skillLevels.size()) { throw new IllegalArgumentException(); }

    IntStream.range(0, skillLevels.size()).forEach(i -> {
        typeAndConfirm(languagesFld.get(i), languages.get(i));
        typeAndConfirm(skillFld.get(i), skillLevels.get(i).getLangSkill());
    });
}

IntStream is used, so i-th language-skillLevel pair is inserted in i-th row.

SkillLevel is an enum which implements getLangSkill() method which returns, one of four proficiency levels as String

However, there is a risk that the user can provide Lists of different sizes (although guarded) or that they could mix up the order and give themselves the wrong proficiency scores.

AFAIK there are no tuples in Java. I tried using Map, but I can't see any method that could let me use i-th element of map.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

郁金香雨 2025-02-14 11:00:21

不要滥用

这两个数据: Language Level 不要单独具有任何值,只有当您拥有它们两者都是有用的。这意味着他们必须构成一个对象。尝试使用 MAP 的尝试只是为了描述这两个属性之间的关系,这将是滥用收集的内容,这将导致无可限制的代码。

因此,您可以定义a 记录 或a class 如果您希望它是可变的或更早使用版本比Java 16 )将这两个属性组合到一个对象中:

public record LanguageLevel(String language, SkillLevel level) {}

用它而不是 list&lt; string&gt; and list&lt; skill&lt; skill&gt; 您将处理一个 list&lt; languagelevel&gt;

如果您想对列表中的对象进行排序,并且只有一种特定的分类方式在您的应用程序中有意义 - 所谓的自然顺序,那么您可以制作 languagelevel 实施可比性 接口。

但是,如果在您的域模型中,这些对没有自然顺序,并且它们的分类可能会有所不同,具体取决于 比较>比较>比较 接口。

您可以定义多个比较器以促进不同的分类方式。例如:

Comparator<LanguageLevel> bySkillDescAndByLang = 
    Comparator.comparing(LanguageLevel::level).reversed() // assumption that SkillLevel implements Comparable<SkillLevel>
        .thenComparing(LanguageLevel::language);

List<LanguageLevel> languages = // initialize the list
languages.sort(bySkillDescAndByLang);

Don't misuse Collections

The two pieces of data: language and level don't a have any value separately, only when you have them both they are useful. That means they have to constitute an object. An attempt to utilize a Map just for the purpose of describing the relationship between the two properties would be an abuse of collection, which would result in unmaintainable code.

So instead of maintaining the two separate lists, which makes your code brittle, you can define a record (or a class if you want it to be mutable or using a version earlier than Java 16) that will combine both properties into a single object:

public record LanguageLevel(String language, SkillLevel level) {}

With that instead of List<String> and List<SkillLevel> you will deal with a List<LanguageLevel>.

In case if you would want to sort the objects in a list and there's only one particular way of sorting that makes sense in your application - so called natural order, then you can make LanguageLevel implement Comparable interface.

But if in your domain model, these pairs have no natural order, and they might be sorted differently depending on a situation that have a look at the Comparator interface.

You can define multiple comparators to facilitate different ways of sorting. For example:

Comparator<LanguageLevel> bySkillDescAndByLang = 
    Comparator.comparing(LanguageLevel::level).reversed() // assumption that SkillLevel implements Comparable<SkillLevel>
        .thenComparing(LanguageLevel::language);

List<LanguageLevel> languages = // initialize the list
languages.sort(bySkillDescAndByLang);
指尖上得阳光 2025-02-14 11:00:21

要么:

的地图方法:

NavigableMap < String , SkillLevel > map = new TreeMap<>() ;
map.put( someLangString , someSkillLevel ) ;
map.put( someOtherLangString , someOtherSkillLevel ) ;
…

键值对将通过字符串键的自然顺序自动排序。

Either:

  • Use a NavigableMap such as TreeMap
  • Define a record (a nominal tuple) with two member fields that implements Comparable

For the map approach:

NavigableMap < String , SkillLevel > map = new TreeMap<>() ;
map.put( someLangString , someSkillLevel ) ;
map.put( someOtherLangString , someOtherSkillLevel ) ;
…

The key-value pairs will be automatically sorted by the natural order of the string keys.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文