简体   繁体   中英

How to find the max number of an unique string element in a alphanumeric Array list in java

I have list that has alphanumeric elements. I want to find the maximum number of each elements individually.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Collect {
    public static void main(String[] args) {

        List<String> alphaNumericList = new ArrayList<String>();
        alphaNumericList.add("Demo.23");
        alphaNumericList.add("Demo.1000");
        alphaNumericList.add("Demo.12");
        alphaNumericList.add("Demo.12");
        alphaNumericList.add("Test.01");
        alphaNumericList.add("Test.02");
        alphaNumericList.add("Test.100");
        alphaNumericList.add("Test.99");

        Collections.sort(alphaNumericList);
        System.out.println("Output "+Arrays.asList(alphaNumericList));

    }

I need filter only below values. For that I am sorting the list but it filters based on the string rather than int value. I want to achieve in an efficient way. Please suggest on this. Demo.1000 Test.100

Output [[Demo.1000, Demo.12, Demo.12, Demo.23, Test.01, Test.02, Test.100, Test.99]]

You can either create a special AlphaNumericList type, wrapping the array list or whatever collection(s) you want to use internally, giving it a nice public interface to work with, or for the simplest case if you want to stick to the ArrayList<String> , just use a Comparator for sort(..) :

package de.scrum_master.stackoverflow.q60482676;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static java.lang.Integer.parseInt;

public class Collect {
  public static void main(String[] args) {
    List<String> alphaNumericList = Arrays.asList(
      "Demo.23", "Demo.1000", "Demo.12", "Demo.12",
      "Test.01", "Test.02", "Test.100", "Test.99"
    );

    Collections.sort(
      alphaNumericList,
      (o1, o2) ->
        ((Integer) parseInt(o1.split("[.]")[1])).compareTo(parseInt(o2.split("[.]")[1]))
    );
    System.out.println("Output " + alphaNumericList);
  }
}

This will yield the following console log:

Output [Test.01, Test.02, Demo.12, Demo.12, Demo.23, Test.99, Test.100, Demo.1000]

Please let me know if you don't understand lambda syntax. You can also use an anonymous class instead like in pre-8 versions of Java.


Update 1: If you want to refactor the one-line lambda for better readability, maybe you prefer this:

    Collections.sort(
      alphaNumericList,
      (text1, text2) -> {
        Integer number1 = parseInt(text1.split("[.]")[1]);
        int number2 = parseInt(text2.split("[.]")[1]);
        return number1.compareTo(number2);
      }
    );

Update 2: If more than one dot "." character can occur in your strings, you need to get the numeric substring in a different way via regex match, still not complicated:

    Collections.sort(
      alphaNumericList,
      (text1, text2) -> {
        Integer number1 = parseInt(text1.replaceFirst(".*[.]", ""));
        int number2 = parseInt(text2.replaceFirst(".*[.]", ""));
        return number1.compareTo(number2);
      }
    );

Update 3: I just noticed that for some weird reason you put the sorted list into another list via Arrays.asList(alphaNumericList) when printing. I have replaced that by just alphaNumericList in the code above and also updated the console log. Before the output was like [[foo, bar, zot]] , ie a nested list with one element.

Using stream and toMap() collector.

Map<String, Long> result = alphaNumericList.stream().collect(
       toMap(k -> k.split("\\.")[0], v -> Long.parseLong(v.split("\\.")[1]), maxBy(Long::compare)));

The result map will contain word part as a key and maximum number as a value of the map(in your example the map will contain {Demo=1000, Test=100} )

Check below answer:

public static void main(String[] args) {
    List<String> alphaNumericList = new ArrayList<String>();
    alphaNumericList.add("Demo.23");
    alphaNumericList.add("Demo.1000");
    alphaNumericList.add("Demo.12");
    alphaNumericList.add("Demo.12");
    alphaNumericList.add("Test.01");
    alphaNumericList.add("Test.02");
    alphaNumericList.add("Test.100");
    alphaNumericList.add("Test.99");

    Map<String, List<Integer>> map = new HashMap<>();

    for (String val : alphaNumericList) {
        String key = val.split("\\.")[0];
        Integer value = Integer.valueOf(val.split("\\.")[1]);

        if (map.containsKey(key)) {
            map.get(key).add(value);
        } else {
            List<Integer> intList = new ArrayList<>();
            intList.add(value);
            map.put(key, intList);
        }
    }

    for (Map.Entry<String, List<Integer>> entry : map.entrySet()) {
        List<Integer> valueList = entry.getValue();
        Collections.sort(valueList, Collections.reverseOrder());
        System.out.print(entry.getKey() + "." + valueList.get(0) + " ");
    }
}

a. Assuming there are string of type Demo. and Test. in your arraylist. b.It should be trivial to filter out elements with String Demo. and then extract the max integer for same. c. Same should be applicable for extracting out max number associated with Test. Please check the following snippet of code to achieve the same.

 Set<String> uniqueString = alphaNumericList.stream().map(c->c.replaceAll("\\.[0-9]*","")).collect(Collectors.toSet());
    Map<String,Integer> map = new HashMap<>();

    for(String s:uniqueString){
      int max=  alphaNumericList.stream().filter(c -> c.startsWith(s+".")).map(c -> c.replaceAll(s+"\\.","")).map(c-> Integer.parseInt(c)).max(Integer::compare).get();
        map.put(s,max);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM